国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

STM32學(xué)習(xí)——半天學(xué)完正點(diǎn)原子入門篇例程,STM32:學(xué)會(huì)了嗎?我:學(xué)廢了?

MingjunYang / 2550人閱讀

本文代碼均來正點(diǎn)原子標(biāo)準(zhǔn)例程
聲明:本文不是教學(xué)文章,可能也不適合初學(xué)者閱讀

不知為什么,最近總蹦出有很多想法(可能是工作太閑了)一會(huì)想學(xué)這,一會(huì)想學(xué)那,這不,突然想復(fù)習(xí)一下STM32了。

我好久以前就學(xué)過正點(diǎn)原子的課程,還買過一些開發(fā)板,但現(xiàn)在手上只有一個(gè)核心板了,就暫且湊合著用吧。

我是個(gè)喜歡制定計(jì)劃的人,既然有了想法,那就得制定一個(gè)學(xué)習(xí)計(jì)劃,估摸了一下,明天要上班,現(xiàn)在已經(jīng)中午了,所以我只有一個(gè)下午加一個(gè)晚上的時(shí)間。哎?,工作之后發(fā)現(xiàn)學(xué)習(xí)的時(shí)間太少了,所以,既然是復(fù)習(xí),那就不搞那么多彎彎繞繞了,直接針對(duì)正點(diǎn)原子的代碼,通過代碼學(xué)習(xí)STM32,那些啥原理的,通通給我拋到九霄云外去,以后有機(jī)會(huì)慢慢整。

開發(fā)平臺(tái)

話不多說,開始整活,先準(zhǔn)備一下硬件:

就一個(gè)核心板,太寒酸了,還好有個(gè)屏幕撐撐場面。核心板的MCU型號(hào)為STM32F103ZET6。

有了硬件,就差代碼了。
下圖是正點(diǎn)原子的入門篇視頻,我就按照這個(gè)順序來學(xué)一遍(沒有硬件支持的話,就只能跳過了,如OLED),寄存器版的就不考慮了,太麻煩。

雖然從教學(xué)視頻的目錄上看感覺實(shí)驗(yàn)多得有些嚇人,但打開工程文件夾一看,嘿嘿,舒服了。?,這么一點(diǎn),一下午就能搞完。

就在我竊喜的時(shí)候,看了一眼時(shí)間,時(shí)間不多了,抓緊了?。。。

實(shí)驗(yàn)1 跑馬燈實(shí)驗(yàn)

main()

光看主函數(shù),覺得他和51一樣簡單,就是初始化和設(shè)置GPIO的高低,但實(shí)際上它們有本質(zhì)區(qū)別,畢竟一個(gè)是8位,一個(gè)是32位。下面我們來一行行地分析吧。

int main(void){  	delay_init();		  //初始化延時(shí)函數(shù)	LED_Init();		        //初始化LED端口	while(1)	{			GPIO_ResetBits(GPIOB,GPIO_Pin_5);  //LED0對(duì)應(yīng)引腳GPIOB.5拉低,亮  等同LED0=0;			GPIO_SetBits(GPIOE,GPIO_Pin_5);   //LED1對(duì)應(yīng)引腳GPIOE.5拉高,滅 等同LED1=1;			delay_ms(300);  		   //延時(shí)300ms			GPIO_SetBits(GPIOB,GPIO_Pin_5);	   //LED0對(duì)應(yīng)引腳GPIOB.5拉高,滅  等同LED0=1;			GPIO_ResetBits(GPIOE,GPIO_Pin_5); //LED1對(duì)應(yīng)引腳GPIOE.5拉低,亮 等同LED1=0;			delay_ms(300);                     //延時(shí)300ms	}} 

delay_init() 函數(shù)

//初始化延遲函數(shù)//SYSTICK的時(shí)鐘固定為HCLK時(shí)鐘的1/8//SYSCLK:系統(tǒng)時(shí)鐘void delay_init(){	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//選擇外部時(shí)鐘  HCLK/8	fac_us=SystemCoreClock/8000000;				//為系統(tǒng)時(shí)鐘的1/8  	fac_ms=(u16)fac_us*1000;					//非OS下,代表每個(gè)ms需要的systick時(shí)鐘數(shù)   }								    

第一個(gè)函數(shù)delay_init(),不像51里直接用一個(gè)while實(shí)現(xiàn)延時(shí),這里的延時(shí)由滴答定時(shí)器實(shí)現(xiàn)。Systick定時(shí)器就是系統(tǒng)滴答定時(shí)器,一個(gè)24 位的倒計(jì)數(shù)定時(shí)器,計(jì)到0 時(shí),將從RELOAD 寄存器中自動(dòng)重裝載定時(shí)初值。只要不把它在SysTick 控制及狀態(tài)寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。
SysTick_CLKSourceConfig是一個(gè)庫函數(shù),作用是配置滴答定時(shí)器的時(shí)鐘源。

STM32 有5個(gè)時(shí)鐘源:HSI、HSE、LSI、LSE、PLL。
①、HSI是高速內(nèi)部時(shí)鐘,RC振蕩器,頻率為8MHz,精度不高。
②、HSE是高速外部時(shí)鐘,可接石英/陶瓷諧振器,或者接外部時(shí)鐘源,頻率范圍為4MHz~16MHz。
③、LSI是低速內(nèi)部時(shí)鐘,RC振蕩器,頻率為40kHz,提供低功耗時(shí)鐘。WDG
④、LSE是低速外部時(shí)鐘,接頻率為32.768kHz的石英晶體。RTC
⑤、PLL為鎖相環(huán)倍頻輸出,其時(shí)鐘輸入源可選擇為HSI/2、HSE或者HSE/2。
倍頻可選擇為2~16倍,但是其輸出頻率最大不得超過72MHz。

STM32時(shí)鐘源的知識(shí)還是挺多的,我自己現(xiàn)在也不是很清楚(得專門抽空學(xué)學(xué)),但我知道如果沒有做配置,系統(tǒng)默認(rèn)時(shí)鐘頻率是最高頻率——本平臺(tái)為72MHz
system_stm32f10x.c里有以下內(nèi)容,先記錄一下,以后再分析。

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)/* #define SYSCLK_FREQ_HSE    HSE_VALUE */ #define SYSCLK_FREQ_24MHz  24000000#else/* #define SYSCLK_FREQ_HSE    HSE_VALUE *//* #define SYSCLK_FREQ_24MHz  24000000 */ /* #define SYSCLK_FREQ_36MHz  36000000 *//* #define SYSCLK_FREQ_48MHz  48000000 *//* #define SYSCLK_FREQ_56MHz  56000000 */#define SYSCLK_FREQ_72MHz  72000000#endif

SysTick_CLKSourceConfig(…)

下面看看滴答定時(shí)器時(shí)鐘源配置的庫函數(shù)源碼,可以看出它的時(shí)鐘源只能為SysTick_CLKSource_HCLK_Div8SysTick_CLKSource_HCLK,那么問題來了,什么是HCLK:

HCLK :AHB總線時(shí)鐘,由系統(tǒng)時(shí)鐘SYSCLK 分頻得到,一般不分頻,等于系統(tǒng)時(shí)鐘

剛剛提到系統(tǒng)時(shí)鐘為72M,所以SysTick_CLKSource_HCLK_Div8 就是72/8=9M。

/**  * @brief  Configures the SysTick clock source.  * @param  SysTick_CLKSource: specifies the SysTick clock source.  *   This parameter can be one of the following values:  *     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.  *     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.  * @retval None  */void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource){  /* Check the parameters */  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)  {    SysTick->CTRL |= SysTick_CLKSource_HCLK;  }  else  {    SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;  }}

配置完了滴答定時(shí)器的時(shí)鐘,delay_init函數(shù)內(nèi)還有兩行:

fac_us=SystemCoreClock/8000000;	//為系統(tǒng)時(shí)鐘的1/8  fac_ms=(u16)fac_us*1000;		//非OS下,代表每個(gè)ms需要的systick時(shí)鐘數(shù)   		

fac_us表示微秒的計(jì)時(shí)因子,即滴答計(jì)時(shí)器重載值為1*fac_us時(shí),計(jì)時(shí)時(shí)間為1us(可以看后面的delay_us函數(shù)),fac_ms為fac_us的1000倍,自然就是1ms了。

  • 那么問題來了,為什么fac_us代表1us呢?

之前我們提到
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //選擇外部時(shí)鐘 HCLK/8
即滴答定時(shí)器定時(shí)器頻率為9M(72/8),9M意味著定時(shí)器1秒計(jì)數(shù)9000000,那么1毫秒計(jì)數(shù)就為9000,1微秒為9。這代表什么?計(jì)9次數(shù)為1us,這個(gè)9就是1微秒的計(jì)數(shù)因子(fac_us),即fac_us(72000000/8000000=9)代表1us。n微秒則為n * fac_us。

LED_Init() 函數(shù)

終于到了本實(shí)驗(yàn)的主角——LED(GPIO)

//初始化PB5和PE5為輸出口.并使能這兩個(gè)口的時(shí)鐘		    //LED IO初始化void LED_Init(void){  GPIO_InitTypeDef  GPIO_InitStructure; 	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);	 //使能PB,PE端口時(shí)鐘	 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //LED0-->PB.5 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽輸出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度為50MHz GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根據(jù)設(shè)定參數(shù)初始化GPIOB.5 GPIO_SetBits(GPIOB,GPIO_Pin_5);						 //PB.5 輸出高 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	    		 //LED1-->PE.5 端口配置, 推挽輸出 GPIO_Init(GPIOE, &GPIO_InitStructure);	  				 //推挽輸出 ,IO口速度為50MHz GPIO_SetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 輸出高 }

概括一下配置GPIO的步驟:

  1. 定義一個(gè)GPIO_InitTypeDef 成員
  2. 使能GPIO對(duì)應(yīng)的端口時(shí)鐘RCC_APB2PeriphClockCmd(...)
  3. 配置引腳GPIO_Pin
  4. 配置模式(輸入、輸出、推挽、開漏、浮空)GPIO_Mode
  5. 配置IO速度(我練習(xí)時(shí)一般不太在意這一項(xiàng))GPIO_Speed
  6. 初始化GPIO_InitTypeDef 成員GPIO_Init(..)
  7. 設(shè)置引腳高低狀態(tài)GPIO_SetBits(..)GPIO_ResetBits(...)

RCC_APB2PeriphClockCmd(…)

庫函數(shù)注釋中標(biāo)明了時(shí)鐘總線上的外設(shè),GPIOB和GPIOE都在APB2總線上

/**  * @brief  Enables or disables the High Speed APB (APB2) peripheral clock.  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.  *   This parameter can be any combination of the following values:  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11       * @param  NewState: new state of the specified peripheral clock.  *   This parameter can be: ENABLE or DISABLE.  * @retval None  */void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState){  /* Check the parameters */  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));  assert_param(IS_FUNCTIONAL_STATE(NewState));  if (NewState != DISABLE)  {    RCC->APB2ENR |= RCC_APB2Periph;  }  else  {    RCC->APB2ENR &= ~RCC_APB2Periph;  }}

如果想快速查到某外設(shè)的時(shí)鐘總線,可以參考《STM32中文參考手冊(cè)》存儲(chǔ)器和總線架構(gòu)章節(jié):

GPIO_InitTypeDef

下面是GPIO_InitTypeDef結(jié)構(gòu)體定義

/**   * @brief  GPIO Init structure definition    */typedef struct{  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.                                      This parameter can be any value of @ref GPIO_pins_define */  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.                                      This parameter can be a value of @ref GPIOMode_TypeDef */}GPIO_InitTypeDef;

LED_init中,LED0GPIO_Pin為GPIOB5,LED1為GPIOE5;
模式都選擇了推挽輸出

推挽輸出的最大特點(diǎn)是可以真正能真正的輸出高電平和低電平,在兩種電平下都具有驅(qū)動(dòng)能力。

由LED的原理圖可以知道它們?yōu)楣碴枠O,所以默認(rèn)要將IO拉高。


其他細(xì)節(jié)感興趣的可以自己去研究?。

delay_ms(…)函數(shù)

fac_ms剛剛在延時(shí)函數(shù)初始化中已經(jīng)介紹,滴答定時(shí)器SysTick每計(jì)時(shí)fac_ms次,則表示1ms,所以nms*fac_ms表示計(jì)時(shí)nms毫秒。SysTick->LOAD為定時(shí)器的重載值,SysTick->VAL表示計(jì)數(shù)值,還要注意:滴答定時(shí)器是倒數(shù)計(jì)數(shù)的。SysTick->CTRL為控制寄存器,第16位可以用來檢測是否倒數(shù)到0。

void delay_ms(u16 nms){	 		  	  	u32 temp;		   	SysTick->LOAD=(u32)nms*fac_ms;				//時(shí)間加載(SysTick->LOAD為24bit)	SysTick->VAL =0x00;							//清空計(jì)數(shù)器	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//開始倒數(shù)  	do	{		temp=SysTick->CTRL;	}while((temp&0x01)&&!(temp&(1<<16)));		//等待時(shí)間到達(dá)   	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//關(guān)閉計(jì)數(shù)器	SysTick->VAL =0X00;       					//清空計(jì)數(shù)器	  	    } 

位操作

對(duì)于操作寄存器,經(jīng)常要用到位操作,如SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk中,SysTick_CTRL_ENABLE_Msk表示1,SysTick->CTRL|=1的作用是將CTRL寄存器的最低位置1,而不影響其他高19位(0或任何二進(jìn)制數(shù),都會(huì)是它自己);
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;的作用是將CTRL最低位置0,0x00000001按位取反后為0xfffffffe,該數(shù)與任何32位數(shù)按位與(&),都不會(huì)影響高31位,因?yàn)?和任何二進(jìn)制數(shù)進(jìn)行與運(yùn)算都等于它自己。


本來想寫位帶操作的,但看了看時(shí)間,就放棄了


GPIO引腳控制函數(shù)就不提了,之前在LED_Init()函數(shù)里已經(jīng)見過。
實(shí)驗(yàn)效果——紅綠燈交替閃爍。

實(shí)驗(yàn)2 按鍵輸入

main()

主函數(shù)中LED0、LED1和BEEP代表的是GPIO的位段(本文忽略這個(gè)概念),把它當(dāng)做51里對(duì)GPIO的位操作就行了。
與上一個(gè)實(shí)驗(yàn)相比,本實(shí)驗(yàn)多了按鍵模塊和蜂鳴器模塊。

int main(void) { 	vu8 key=0;		delay_init();	    	 //延時(shí)函數(shù)初始化	   	LED_Init();			     //LED端口初始化	KEY_Init();          	//初始化與按鍵連接的硬件接口	BEEP_Init();         	//初始化蜂鳴器端口	LED0=0;					//先點(diǎn)亮紅燈	while(1)	{ 		key=KEY_Scan(0);	//得到鍵值	   	if(key)		{						   			switch(key)			{				 				case WKUP_PRES:	//控制LED1翻轉(zhuǎn)						LED1=!LED1;					BEEP = !BEEP;					break;				case KEY0_PRES:	//同時(shí)控制LED0翻轉(zhuǎn) 					LED0=!LED0;					BEEP = !BEEP;					break;			}		}else delay_ms(10); 	}	 }

KEY_Init()函數(shù)

與LED_Init()類似,配置步驟相同(配置步驟見LED_Init()介紹部分)。

void KEY_Init(void) //IO初始化{  	GPIO_InitTypeDef GPIO_InitStructure;  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE時(shí)鐘	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_4;//KEY0	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //設(shè)置成下拉輸入 	GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4	//初始化 WK_UP-->GPIOA.0	  下拉輸入	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0設(shè)置成輸入,默認(rèn)下拉	  	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0}

開發(fā)板上有兩個(gè)按鍵,KEY_UPKEY0,都是一端接高電平,一端接IO,所以模式設(shè)置為下拉輸入,KEY_UP對(duì)應(yīng)的GPIO引腳為GPIOA0,KEY0對(duì)應(yīng)的引腳為GPIOE4。IO時(shí)鐘都掛載在APB2上。


BEEP_Init()函數(shù)

開發(fā)板上并沒有蜂鳴器,我選擇了外接一個(gè)蜂鳴器,同樣接在PB8引腳上。初始化配置步驟和LED與KEY相同,模式為推挽輸出,由于我的蜂鳴器低電平有效,所以初始化中還需把IO電平拉高。

//初始化PB8為輸出口.并使能這個(gè)口的時(shí)鐘		    //蜂鳴器初始化void BEEP_Init(void){  GPIO_InitTypeDef  GPIO_InitStructure; 	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能GPIOB端口時(shí)鐘  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;				 //BEEP-->PB.8 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽輸出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 //速度為50MHz GPIO_Init(GPIOB, &GPIO_InitStructure);	 //根據(jù)參數(shù)初始化GPIOB.8  GPIO_SetBits(GPIOB,GPIO_Pin_8);//輸出0,關(guān)閉蜂鳴器輸出}

KEY_Scan(…)函數(shù)

該函數(shù)中,mode表示模式,為0表示短按,為1表示長按。局部靜態(tài)變量key_up默認(rèn)為1,表示按鍵處于空閑狀態(tài)(松開)。
如果選擇短按,在按鍵處于空閑狀態(tài)時(shí),檢測到KEY0WK_UP中任意一個(gè)按鍵被按下,則將key_up置0,在此期間不處理其他按鍵判斷,函數(shù)返回值為按鍵值或0(無按鍵);當(dāng)按鍵松開,程序再次運(yùn)行到按鍵掃描函數(shù)中時(shí),key_up置為1,按鍵再次回到空閑狀態(tài)。
如果選擇長按,則key_up恒為1,無論是否有按鍵正處于按下狀態(tài),每次進(jìn)入KEY_Scan函數(shù)都進(jìn)行按鍵判斷,這樣就實(shí)現(xiàn)了按鍵的長按檢測。

u8 KEY_Scan(u8 mode){	 	static u8 key_up=1;//按鍵按松開標(biāo)志	if(mode)key_up=1;  //支持連按		  	if(key_up&&(KEY0==1||WK_UP==1))	{		delay_ms(10);//去抖動(dòng) 		key_up=0;		if(KEY0==1)return KEY0_PRES;		else if(WK_UP==1)return WKUP_PRES;	}else if(KEY0==0&&WK_UP==0)key_up=1; 	     	return 0;// 無按鍵按下}

實(shí)驗(yàn)3 串口實(shí)驗(yàn)

mian()

與前兩個(gè)實(shí)驗(yàn)相比,串口實(shí)驗(yàn)增加了NVIC中斷配置、串口初始化配置。main函數(shù)實(shí)現(xiàn)的功能為:單片機(jī)不停地向串口發(fā)送提示性數(shù)據(jù),如果有外部設(shè)備通過串口向單片機(jī)發(fā)送數(shù)據(jù)(以“/r/n“作為結(jié)束符),單片機(jī)接收數(shù)據(jù)并返回給外部設(shè)備。

 int main(void) {		 	u16 t;  	u16 len;		u16 times=0;	delay_init();	    	 //延時(shí)函數(shù)初始化	  	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)	uart_init(115200);	 //串口初始化為115200 	LED_Init();			     //LED端口初始化	KEY_Init();          //初始化與按鍵連接的硬件接口 	while(1)	{		if(USART_RX_STA&0x8000)		{					   			len=USART_RX_STA&0x3fff;//得到此次接收到的數(shù)據(jù)長度			printf("/r/n您發(fā)送的消息為:/r/n/r/n");			for(t=0;t<len;t++)			{				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1發(fā)送數(shù)據(jù)				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發(fā)送結(jié)束			}			printf("/r/n/r/n");//插入換行			USART_RX_STA=0;		}else		{			times++;			if(times%5000==0)			{				printf("/r/n戰(zhàn)艦STM32開發(fā)板 串口實(shí)驗(yàn)/r/n");				printf("正點(diǎn)原子@ALIENTEK/r/n/r/n");			}			if(times%200==0)printf("請(qǐng)輸入數(shù)據(jù),以回車鍵結(jié)束/n");  			if(times%30==0)LED0=!LED0;//閃爍LED,提示系統(tǒng)正在運(yùn)行.			delay_ms(10);   		}	}	  }

NVIC_PriorityGroupConfig

NVIC:嵌套向量中斷控制器,NVIC_PriorityGroupConfig函數(shù)是中斷優(yōu)先級(jí)的分組配置函數(shù)。

/**  * @brief  Configures the priority grouping: pre-emption priority and subpriority.  * @param  NVIC_PriorityGroup: specifies the priority grouping bits length.   *   This parameter can be one of the following values:  *     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority  *                                4 bits for subpriority  *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority  *                                3 bits for subpriority  *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority  *                                2 bits for subpriority  *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority  *                                1 bits for subpriority  *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority  *                                0 bits for subpriority  * @retval None  */void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup){  /* Check the parameters */  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));    /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;}

中斷優(yōu)先級(jí)分為搶占式優(yōu)先級(jí)響應(yīng)優(yōu)先級(jí),搶占優(yōu)先級(jí)越高的先處理,當(dāng)兩個(gè)中斷向量的搶占優(yōu)先級(jí)相同時(shí),如果兩個(gè)中斷同時(shí)到達(dá), 則先處理響應(yīng)優(yōu)先級(jí)高的中斷。

如果對(duì)兩種優(yōu)先級(jí)的位數(shù)分配進(jìn)行分組,可以分為5組(0~4),分組配置是在寄存器SCB->AIRCR中配置:

main函數(shù)中,分組為:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)

注:這個(gè)分組只是設(shè)置STM32中斷的兩種優(yōu)先級(jí)可選范圍,比如0組中,沒有搶占優(yōu)先級(jí),一般情況(學(xué)習(xí)過程中)該配置設(shè)置為2組就行了。另外,這個(gè)分組是全局的,所以一個(gè)程序中只需要配置一次,多次配置可能會(huì)導(dǎo)致未知錯(cuò)誤。

uart_init(…)函數(shù)

串口初始化函數(shù)里不僅有GPIO初始化,還有UART初始化和NVIC初始化。

void uart_init(u32 bound){  //GPIO端口設(shè)置  GPIO_InitTypeDef GPIO_InitStructure;	USART_InitTypeDef USART_InitStructure;	NVIC_InitTypeDef NVIC_InitStructure;	 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA時(shí)鐘  	//USART1_TX   GPIOA.9  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//復(fù)用推挽輸出  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9     //USART1_RX	  GPIOA.10初始化  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10    //Usart1 NVIC 配置  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級(jí)3	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子優(yōu)先級(jí)3	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能	NVIC_Init(&NVIC_InitStructure);	//根據(jù)指定的參數(shù)初始化VIC寄存器     //USART 初始化設(shè)置	USART_InitStructure.USART_BaudRate = bound;//串口波特率	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數(shù)據(jù)格式	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位	USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗(yàn)位	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收發(fā)模式  USART_Init(USART1, &USART_InitStructure); //初始化串口1  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串口接受中斷  USART_Cmd(USART1, ENABLE);                    //使能串口1 }

從原理圖可知串口的發(fā)送IO為GPIOA9,接收IO為GPIOA10,TX(PA9)設(shè)置為復(fù)用推挽輸出(PA9為復(fù)用引腳,可以通過設(shè)置復(fù)用推挽輸出完成USART_TX功能的配置,另外還可以通過配合復(fù)用寄存器方式實(shí)現(xiàn)復(fù)用,如PWM實(shí)驗(yàn)),RX設(shè)置為浮空輸入。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/121284.html

相關(guān)文章

  • stm32mini開發(fā)板lora模塊例程中中文字庫更新失敗的解決方案

    摘要:此文章用于解決開發(fā)板的模塊中文字庫加載問題,也可用于其它關(guān)于中文字庫無法加載的問題。如下圖,已經(jīng)完成了中文字庫燒入,無需再掛載。 正點(diǎn)原子stm32mini板lor...

    longmon 評(píng)論0 收藏0
  • 2021-09-04

    摘要:使用實(shí)現(xiàn)連網(wǎng)實(shí)現(xiàn)巴法云物聯(lián)網(wǎng)使用硬件程序思路基于正點(diǎn)原子的測試程序在巴法云物聯(lián)網(wǎng)創(chuàng)建的主題初始化代碼比較簡陋主函數(shù)代碼如果想用串口助手調(diào)試,接線方法如下使用硬件我這里使用的是正點(diǎn)原子家的開發(fā)板精英版和模塊。 ...

    Zack 評(píng)論0 收藏0
  • STM32入門學(xué)習(xí)經(jīng)驗(yàn)總結(jié)

    摘要:嚴(yán)格地說,應(yīng)該是模仿實(shí)驗(yàn)。為什么覺得無從下手,看資料沒有頭緒經(jīng)驗(yàn)總結(jié)看資料需要計(jì)劃耐心和速度這里所謂的資料包括書籍文檔。建議有報(bào)銷條件的同學(xué)自己設(shè)計(jì)一塊板子學(xué)習(xí)。無法報(bào)銷的同學(xué),可以選購一款開發(fā)板學(xué)習(xí)。 STM32系列基于專為要求高性能、低成本、低功耗的嵌入式應(yīng)用專門設(shè)計(jì)的ARMCortex...

    biaoxiaoduan 評(píng)論0 收藏0
  • 基于STM32Cube MX開發(fā)的TencentOS-Tiny軟件包

    摘要:基于開發(fā)的軟件包導(dǎo)師汪禮超學(xué)員崔林威摘要騰訊物聯(lián)網(wǎng)操作系統(tǒng)是騰訊面向物聯(lián)網(wǎng)領(lǐng)域開發(fā)的實(shí)時(shí)操作系統(tǒng),具有低功耗,低資源占用,模塊化,可裁剪等特性。圖中斷函數(shù)處理進(jìn)行生成工程配置,按如下界面進(jìn)行配置,最后點(diǎn)擊,并點(diǎn)擊。 ...

    shiyang6017 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<