本文代碼均來正點原子標準例程
聲明:本文不是教學文章,可能也不適合初學者閱讀
不知為什么,最近總蹦出有很多想法(可能是工作太閑了)一會想學這,一會想學那,這不,突然想復習一下STM32
了。
我好久以前就學過正點原子的課程,還買過一些開發板,但現在手上只有一個核心板了,就暫且湊合著用吧。
我是個喜歡制定計劃的人,既然有了想法,那就得制定一個學習計劃,估摸了一下,明天要上班,現在已經中午了,所以我只有一個下午加一個晚上的時間。哎?,工作之后發現學習的時間太少了,所以,既然是復習,那就不搞那么多彎彎繞繞了,直接針對正點原子的代碼,通過代碼學習STM32,那些啥原理的,通通給我拋到九霄云外去,以后有機會慢慢整。
話不多說,開始整活,先準備一下硬件:
就一個核心板,太寒酸了,還好有個屏幕撐撐場面。核心板的MCU型號為STM32F103ZET6。
有了硬件,就差代碼了。
下圖是正點原子的入門篇視頻,我就按照這個順序來學一遍(沒有硬件支持的話,就只能跳過了,如OLED),寄存器版的就不考慮了,太麻煩。
雖然從教學視頻的目錄上看感覺實驗多得有些嚇人,但打開工程文件夾一看,嘿嘿,舒服了。?,這么一點,一下午就能搞完。
就在我竊喜的時候,看了一眼時間,時間不多了,抓緊了?。。。
光看主函數,覺得他和51一樣簡單,就是初始化和設置GPIO的高低,但實際上它們有本質區別,畢竟一個是8位,一個是32位。下面我們來一行行地分析吧。
int main(void){ delay_init(); //初始化延時函數 LED_Init(); //初始化LED端口 while(1) { GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED0對應引腳GPIOB.5拉低,亮 等同LED0=0; GPIO_SetBits(GPIOE,GPIO_Pin_5); //LED1對應引腳GPIOE.5拉高,滅 等同LED1=1; delay_ms(300); //延時300ms GPIO_SetBits(GPIOB,GPIO_Pin_5); //LED0對應引腳GPIOB.5拉高,滅 等同LED0=1; GPIO_ResetBits(GPIOE,GPIO_Pin_5); //LED1對應引腳GPIOE.5拉低,亮 等同LED1=0; delay_ms(300); //延時300ms }}
//初始化延遲函數//SYSTICK的時鐘固定為HCLK時鐘的1/8//SYSCLK:系統時鐘void delay_init(){ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //選擇外部時鐘 HCLK/8 fac_us=SystemCoreClock/8000000; //為系統時鐘的1/8 fac_ms=(u16)fac_us*1000; //非OS下,代表每個ms需要的systick時鐘數 }
第一個函數delay_init()
,不像51里直接用一個while實現延時,這里的延時由滴答定時器實現。Systick定時器就是系統滴答定時器,一個24 位的倒計數定時器,計到0 時,將從RELOAD 寄存器中自動重裝載定時初值。只要不把它在SysTick 控制及狀態寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。
SysTick_CLKSourceConfig
是一個庫函數,作用是配置滴答定時器的時鐘源。
STM32 有5個時鐘源:HSI、HSE、LSI、LSE、PLL。
①、HSI是高速內部時鐘,RC振蕩器,頻率為8MHz,精度不高。
②、HSE是高速外部時鐘,可接石英/陶瓷諧振器,或者接外部時鐘源,頻率范圍為4MHz~16MHz。
③、LSI是低速內部時鐘,RC振蕩器,頻率為40kHz,提供低功耗時鐘。WDG
④、LSE是低速外部時鐘,接頻率為32.768kHz的石英晶體。RTC
⑤、PLL為鎖相環倍頻輸出,其時鐘輸入源可選擇為HSI/2、HSE或者HSE/2。
倍頻可選擇為2~16倍,但是其輸出頻率最大不得超過72MHz。
STM32時鐘源的知識還是挺多的,我自己現在也不是很清楚(得專門抽空學學),但我知道如果沒有做配置,系統默認時鐘頻率是最高頻率——本平臺為72MHz
system_stm32f10x.c
里有以下內容,先記錄一下,以后再分析。
#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_CLKSource_HCLK_Div8
或SysTick_CLKSource_HCLK
,那么問題來了,什么是HCLK:
HCLK :AHB總線時鐘,由系統時鐘SYSCLK 分頻得到,一般不分頻,等于系統時鐘
剛剛提到系統時鐘為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; }}
配置完了滴答定時器的時鐘,delay_init函數內還有兩行:
fac_us=SystemCoreClock/8000000; //為系統時鐘的1/8 fac_ms=(u16)fac_us*1000; //非OS下,代表每個ms需要的systick時鐘數
fac_us表示微秒的計時因子,即滴答計時器重載值為1*fac_us時,計時時間為1us(可以看后面的delay_us函數),fac_ms為fac_us的1000倍,自然就是1ms了。
之前我們提到
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //選擇外部時鐘 HCLK/8
即滴答定時器定時器頻率為9M(72/8),9M意味著定時器1秒計數9000000,那么1毫秒計數就為9000,1微秒為9。這代表什么?計9次數為1us,這個9就是1微秒的計數因子(fac_us),即fac_us(72000000/8000000=9)代表1us。n微秒則為n * fac_us。
終于到了本實驗的主角——LED(GPIO)
//初始化PB5和PE5為輸出口.并使能這兩個口的時鐘 //LED IO初始化void LED_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口時鐘 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); //根據設定參數初始化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的步驟:
RCC_APB2PeriphClockCmd(...)
GPIO_Pin
GPIO_Mode
GPIO_Speed
GPIO_Init(..)
GPIO_SetBits(..)
或GPIO_ResetBits(...)
庫函數注釋中標明了時鐘總線上的外設,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; }}
如果想快速查到某外設的時鐘總線,可以參考《STM32中文參考手冊》存儲器和總線架構章節:
下面是GPIO_InitTypeDef
結構體定義
/** * @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中,LED0
的GPIO_Pin
為GPIOB5,LED1
為GPIOE5;
模式都選擇了推挽輸出
推挽輸出的最大特點是可以真正能真正的輸出高電平和低電平,在兩種電平下都具有驅動能力。
由LED的原理圖可以知道它們為共陽極,所以默認要將IO拉高。
其他細節感興趣的可以自己去研究?。
fac_ms剛剛在延時函數初始化中已經介紹,滴答定時器SysTick每計時fac_ms次,則表示1ms,所以nms*fac_ms表示計時nms毫秒。SysTick->LOAD
為定時器的重載值,SysTick->VAL
表示計數值,還要注意:滴答定時器是倒數計數的。SysTick->CTRL
為控制寄存器,第16位可以用來檢測是否倒數到0。
void delay_ms(u16 nms){ u32 temp; SysTick->LOAD=(u32)nms*fac_ms; //時間加載(SysTick->LOAD為24bit) SysTick->VAL =0x00; //清空計數器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //開始倒數 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待時間到達 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //關閉計數器 SysTick->VAL =0X00; //清空計數器 }
對于操作寄存器,經常要用到位操作,如SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk
中,SysTick_CTRL_ENABLE_Msk表示1,SysTick->CTRL|=1的作用是將CTRL寄存器的最低位置1,而不影響其他高19位(0或任何二進制數,都會是它自己);
而SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
的作用是將CTRL最低位置0,0x00000001按位取反后為0xfffffffe,該數與任何32位數按位與(&),都不會影響高31位,因為1和任何二進制數進行與運算都等于它自己。
本來想寫位帶操作的,但看了看時間,就放棄了
GPIO引腳控制函數就不提了,之前在LED_Init()函數里已經見過。
實驗效果——紅綠燈交替閃爍。
主函數中LED0、LED1和BEEP代表的是GPIO的位段(本文忽略這個概念),把它當做51里對GPIO的位操作就行了。
與上一個實驗相比,本實驗多了按鍵模塊和蜂鳴器模塊。
int main(void) { vu8 key=0; delay_init(); //延時函數初始化 LED_Init(); //LED端口初始化 KEY_Init(); //初始化與按鍵連接的硬件接口 BEEP_Init(); //初始化蜂鳴器端口 LED0=0; //先點亮紅燈 while(1) { key=KEY_Scan(0); //得到鍵值 if(key) { switch(key) { case WKUP_PRES: //控制LED1翻轉 LED1=!LED1; BEEP = !BEEP; break; case KEY0_PRES: //同時控制LED0翻轉 LED0=!LED0; BEEP = !BEEP; break; } }else delay_ms(10); } }
與LED_Init()類似,配置步驟相同(配置步驟見LED_Init()介紹部分)。
void KEY_Init(void) //IO初始化{ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE時鐘 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//KEY0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //設置成下拉輸入 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設置成輸入,默認下拉 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0}
開發板上有兩個按鍵,KEY_UP
和KEY0
,都是一端接高電平,一端接IO,所以模式設置為下拉輸入
,KEY_UP對應的GPIO引腳為GPIOA0,KEY0對應的引腳為GPIOE4。IO時鐘都掛載在APB2上。
開發板上并沒有蜂鳴器,我選擇了外接一個蜂鳴器,同樣接在PB8引腳上。初始化配置步驟和LED與KEY相同,模式為推挽輸出
,由于我的蜂鳴器低電平有效,所以初始化中還需把IO電平拉高。
//初始化PB8為輸出口.并使能這個口的時鐘 //蜂鳴器初始化void BEEP_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB端口時鐘 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); //根據參數初始化GPIOB.8 GPIO_SetBits(GPIOB,GPIO_Pin_8);//輸出0,關閉蜂鳴器輸出}
該函數中,mode
表示模式,為0表示短按
,為1表示長按
。局部靜態變量key_up
默認為1,表示按鍵處于空閑狀態(松開)。
如果選擇短按,在按鍵處于空閑狀態時,檢測到KEY0
和WK_UP
中任意一個按鍵被按下,則將key_up
置0,在此期間不處理其他按鍵判斷,函數返回值為按鍵值或0(無按鍵);當按鍵松開,程序再次運行到按鍵掃描函數中時,key_up
置為1,按鍵再次回到空閑狀態。
如果選擇長按,則key_up
恒為1,無論是否有按鍵正處于按下狀態,每次進入KEY_Scan函數都進行按鍵判斷,這樣就實現了按鍵的長按檢測。
u8 KEY_Scan(u8 mode){ static u8 key_up=1;//按鍵按松開標志 if(mode)key_up=1; //支持連按 if(key_up&&(KEY0==1||WK_UP==1)) { delay_ms(10);//去抖動 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;// 無按鍵按下}
與前兩個實驗相比,串口實驗增加了NVIC中斷配置、串口初始化配置。main函數實現的功能為:單片機不停地向串口發送提示性數據,如果有外部設備通過串口向單片機發送數據(以“/r/n“作為結束符),單片機接收數據并返回給外部設備。
int main(void) { u16 t; u16 len; u16 times=0; delay_init(); //延時函數初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級 uart_init(115200); //串口初始化為115200 LED_Init(); //LED端口初始化 KEY_Init(); //初始化與按鍵連接的硬件接口 while(1) { if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff;//得到此次接收到的數據長度 printf("/r/n您發送的消息為:/r/n/r/n"); for(t=0;t<len;t++) { USART_SendData(USART1, USART_RX_BUF[t]);//向串口1發送數據 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發送結束 } printf("/r/n/r/n");//插入換行 USART_RX_STA=0; }else { times++; if(times%5000==0) { printf("/r/n戰艦STM32開發板 串口實驗/r/n"); printf("正點原子@ALIENTEK/r/n/r/n"); } if(times%200==0)printf("請輸入數據,以回車鍵結束/n"); if(times%30==0)LED0=!LED0;//閃爍LED,提示系統正在運行. delay_ms(10); } } }
NVIC:嵌套向量中斷控制器,NVIC_PriorityGroupConfig
函數是中斷優先級的分組配置函數。
/** * @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;}
中斷優先級分為搶占式優先級
和響應優先級
,搶占優先級越高的先處理,當兩個中斷向量的搶占優先級相同時,如果兩個中斷同時到達, 則先處理響應優先級高的中斷。
如果對兩種優先級的位數分配進行分組,可以分為5組(0~4),分組配置是在寄存器SCB->AIRCR中配置:
main函數中,分組為:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
注:這個分組只是設置STM32中斷的兩種優先級可選范圍,比如0組中,沒有搶占優先級,一般情況(學習過程中)該配置設置為2組就行了。另外,這個分組是全局的,所以一個程序中只需要配置一次,多次配置可能會導致未知錯誤。
串口初始化函數里不僅有GPIO初始化,還有UART初始化和NVIC初始化。
void uart_init(u32 bound){ //GPIO端口設置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA時鐘 //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; //復用推挽輸出 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 ;//搶占優先級3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優先級3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化VIC寄存器 //USART 初始化設置 USART_InitStructure.USART_BaudRate = bound;//串口波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位 USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式 USART_Init(USART1, &USART_InitStructure); //初始化串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串口接受中斷 USART_Cmd(USART1, ENABLE); //使能串口1 }
從原理圖可知串口的發送IO為GPIOA9,接收IO為GPIOA10,TX(PA9)設置為復用推挽輸出(PA9為復用引腳,可以通過設置復用推挽輸出完成USART_TX功能的配置,另外還可以通過配合復用寄存器方式實現復用,如PWM實驗),RX設置為浮空輸入。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/121284.html
摘要:此文章用于解決開發板的模塊中文字庫加載問題,也可用于其它關于中文字庫無法加載的問題。如下圖,已經完成了中文字庫燒入,無需再掛載。 正點原子stm32mini板lor...
摘要:使用實現連網實現巴法云物聯網使用硬件程序思路基于正點原子的測試程序在巴法云物聯網創建的主題初始化代碼比較簡陋主函數代碼如果想用串口助手調試,接線方法如下使用硬件我這里使用的是正點原子家的開發板精英版和模塊。 ...
摘要:嚴格地說,應該是模仿實驗。為什么覺得無從下手,看資料沒有頭緒經驗總結看資料需要計劃耐心和速度這里所謂的資料包括書籍文檔。建議有報銷條件的同學自己設計一塊板子學習。無法報銷的同學,可以選購一款開發板學習。 STM32系列基于專為要求高性能、低成本、低功耗的嵌入式應用專門設計的ARMCortex...
摘要:基于開發的軟件包導師汪禮超學員崔林威摘要騰訊物聯網操作系統是騰訊面向物聯網領域開發的實時操作系統,具有低功耗,低資源占用,模塊化,可裁剪等特性。圖中斷函數處理進行生成工程配置,按如下界面進行配置,最后點擊,并點擊。 ...
閱讀 2731·2023-04-26 02:28
閱讀 2565·2021-09-27 13:36
閱讀 3134·2021-09-03 10:29
閱讀 2762·2021-08-26 14:14
閱讀 2111·2019-08-30 15:56
閱讀 841·2019-08-29 13:46
閱讀 2616·2019-08-29 13:15
閱讀 461·2019-08-29 11:29