
要学习STM32,一般文章都会建议使用者先进行基础知识的储备,如学习什么ARM构架、STM32 datasheet等,这往往让学习者感到枯燥,乏味。
前些日子,我通过阅读论坛中大量的资料了解到,其实STM32器件的编程不仅仅局限于对相关寄存器配置和启动方式的学习,为了提高产品的开发,厂家已经为使用者做好了前期的准备,那就是库。对器件的编程要么使用原始方法对器件的寄存器进行一步一步的设置,要么就是使用库文件了。由于比赛的时间都是有限的,如果不适用库的话,估计两三个月不会完成对STM32的学习的。
本菜鸟也是初学者,为了能多掌握一门技术,不得不在较短的时间里(当然不是比赛时间短,而是工作业余时间短,一天才短短的一两个小时,还是牺牲睡觉的时间),更多的学习ARM。我建议大家使用ST的库文件,当然我也是使用库进行学习的。
那么要使用库文件,只听别人滔滔不绝的说,不如亲身体会一下。这就是要学习在MDK下建立工程的目的。


对于一个器件来说,只有实现了输入输出才能体现出它存在的价值,因此学习STM32的GPIO有着重要的意义。
那么如何才能学好GPIO呢?那么你就要对GPIO相关的库文件进行了解。最好的方法就是实践,首先建立一个工程,然后编写GPIO的程序,不断的修改程序,并利用板载的LED观察每次修改的结果,不断的总结经验中就能学到很多知识。
趁热打铁,我自己写的LED流水灯测试程序,代码如下:
/**
******************************************************************************
* @file main.c
* @author th152210
* @version V1.0
* @date 2012/05/07
* @brief four LEDs turn on/off like running water
******************************************************************************
* @description
* four LEDs turn on/off like running water
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#define led GPIOE
#define led1 GPIO_Pin_2
#define led2 GPIO_Pin_3
#define led3 GPIO_Pin_4
#define led4 GPIO_Pin_5
#define ledTurnOn(ledx) GPIO_ResetBits(led , ledx)
#define ledTurnOff(ledx) GPIO_SetBits(led , ledx)
#define ledTurnOnAll() ledTurnOn(gpioInit.GPIO_Pin)
#define ledTurnOffAll() ledTurnOff(gpioInit.GPIO_Pin)
/**
* @brief time delay about 0.3s
* @param none.
* @retval None
*/
void delay(void)
{
uint32_t i,j;
for (i=0;i<1500;i++)
{
for (j=0;j<1000;j++)
{
;
}
}
}
/**
* @brief the main process.
* @note cannt built without it.
* @param none.
* @retval None
*/
main ()
{
GPIO_InitTypeDef gpioInit;
uint16_t count0,count1,count2,count3;
count0 = 0;
//-----initialization------
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //enable APB2 periph
gpioInit.GPIO_Pin = led1|led2|led3|led4;
gpioInit.GPIO_Mode = GPIO_Mode_Out_PP;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(led , &gpioInit); //initialiazate gpio
GPIO_SetBits(led , gpioInit.GPIO_Pin); //set pin
GPIO_ResetBits(led , gpioInit.GPIO_Pin); //reset pin
while (1)
{
for(;count0<8;count0++) //all LEDs light on/off together
{
ledTurnOnAll();
delay();
ledTurnOffAll();
delay();
}
for(;count0<12;count0++) //right turn on one by one
//and turn off all , then left...
{
count1=0;
ledTurnOn (led1);
delay();
ledTurnOn (led2);
delay();
ledTurnOn (led3);
delay();
ledTurnOn (led4);
delay();
ledTurnOffAll();
delay();
ledTurnOn (led4);
delay();
ledTurnOn (led3);
delay();
ledTurnOn (led2);
delay();
ledTurnOn (led1);
delay();
ledTurnOffAll();
delay();
}
for(;count0<16;count0++) //right turn on one by one
//and left turn off one by one
{
count1=0;
ledTurnOn (led1);
delay();
ledTurnOn (led2);
delay();
ledTurnOn (led3);
delay();
ledTurnOn (led4);
delay();
ledTurnOff (led4);
delay();
ledTurnOff (led3);
delay();
ledTurnOff (led2);
delay();
ledTurnOff (led1);
delay();
}
for(;count0<17;count0++)
{
ledTurnOn (led1);
delay();
ledTurnOn (led2);
delay();
ledTurnOn (led3);
delay();
ledTurnOn (led4);
delay();
ledTurnOff (led1);
delay();
ledTurnOff (led2);
delay();
ledTurnOff (led3);
delay();
ledTurnOff (led4);
delay();
}
for(;count0<21;count0++) //left turn on one by one
//and right turn off one by one
{
count1=0;
ledTurnOn (led4);
delay();
ledTurnOn (led3);
delay();
ledTurnOn (led2);
delay();
ledTurnOn (led1);
delay();
ledTurnOff (led1);
delay();
ledTurnOff (led2);
delay();
ledTurnOff (led3);
delay();
ledTurnOff (led4);
delay();
}
}
}
工程文件以及相关视频、图像,明天下班后分享。


我的串口调试程序。开始运行时,先发送一串数据。然后开始等待接收数据
(inputString()),再将接收到的数据发送(putString())出去。我的程序如
下:
/**
******************************************************************************
* @file main.c
* @author th152210
* @version V1.0
* @date 2012/05/07
* @brief USART Send string "www.hi.baidu.com/th152210" per second
******************************************************************************
* @description
* USART Send string "www.hi.baidu.com/th152210" per second , and when it is
* sending the led flashing.then USART send the string it received from the
* computer . for example when it receive "www.hi.baidu.com/th152210" , then it
* will send "www.hi.baidu.com/th152210" to the computer .
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "string.h"
/* Defination ----------*/
//---the port for leds---
#define led GPIOE
#define led1 GPIO_Pin_2
#define led2 GPIO_Pin_3
#define led3 GPIO_Pin_4
#define led4 GPIO_Pin_5
/********var**********/
char usartRxBuffer[256];
/**
* @brief time delay
* @param none.
* @retval None
*/
void delay()
{
vu32 i,j;
for(i=0;i<9000000;i++);
}
/**
* @brief send a data by USART
* @param data : the data for sending
* @retval none
*/
void putChar(uint16_t data)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//wait until empty
USART_SendData(USART1 , data); //send data
}
/**
* @brief send a string by USART
* @param data : the data for sending
* @retval none
*/
void putString(char data[] , uint16_t lenth)
{
uint16_t i;
if(lenth == 0)
{
for(i = 0 ; i < strlen(data); i++)
{
putChar(data[i]); //send one data of data[i]
}
}else
{
for(i = 0 ; i < lenth ; i++)
{
putChar(data[i]); //send one data of data[i]
}
}
}
/**
* @brief receive a data
* @param none
* @retval the data received
*/
uint16_t inputChar()
{
uint16_t data;
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);//wait for the RX no empty bit become 1
data = USART_ReceiveData(USART1);
return data;
}
/**
* @brief receive a string
* @param the string received
* @retval none
*/
char inputString()
{
char data , i;
data = (char)inputChar();
for(i = 0; (data != 0x0D) && (i < 255); i++)
{
usartRxBuffer[i] = data;
data = (char)inputChar();
}
if(i == 255) return 0;
else return 1;
}
/**
* @brief the main
* @param none.
* @retval None
*/
int main (void)
{
GPIO_InitTypeDef gpioInit;
USART_InitTypeDef USART_InitStructure;
char *string;
uint16_t data;
//----- RCC initialization -------
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //enable APB2 periph
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
//RCC_GetClockFreq(&RCC_ClockFreq);
//----- IO initialization -----
gpioInit.GPIO_Pin = led1|led2|led3|led4;
gpioInit.GPIO_Mode = GPIO_Mode_Out_PP;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(led , &gpioInit); //initialiazate gpio
GPIO_SetBits(led , gpioInit.GPIO_Pin); //Set pin
//GPIO_ResetBits(led , gpioInit.GPIO_Pin); //Reset pin
/* Configure USART1 Tx (PA.09) as alternate push-pull */
gpioInit.GPIO_Pin = GPIO_Pin_9;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &gpioInit);
//----- UART initialization ----
//0-----串口参数配置------
USART_InitStructure.USART_BaudRate = 19200; //设置波特率为19200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //设置数据位为8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //设置停止位为1位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //没有硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //send and receive mode
//0-----------------------
USART_Init(USART1, &USART_InitStructure); //initialization USART1
USART_Cmd(USART1 , ENABLE); //enable USART1 modulation
//USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); //disable USART1 interruption
//查询方式发送数据
string = "www.hi.baidu.com/th152210\n";
GPIO_ResetBits(led , led1|led2); //Reset pin
putString(string,0); //send string
GPIO_SetBits(led , led1|led2); //Set pin
while(1)
{
GPIO_ResetBits(led , led3|led4); //Reset pin1 2
inputString();
//data = inputChar();
//delay();
GPIO_SetBits(led , led3|led4); //Set pin1 2
//putString(string,6);
GPIO_ResetBits(led , led1|led2); //Reset pin3 4
//putChar(data);
putString(usartRxBuffer,0);
GPIO_SetBits(led , led1|led2); //Set pin3 4
}
}

XiLiHuTu_template.rar
后期的工程文件都是基于此模板编写的程序。
详细的工程建立工程在此不再赘述,参照以上三大教程就可以自主建立模板。

中断方式的USART程序调试成功,部分代码如下:
main.C中的相关代码:
int main (void)
{
GPIO_InitTypeDef gpioInit;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
char *string;
//----- RCC initialization -------
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO |
RCC_APB2Periph_USART1 , ENABLE);
//RCC_GetClockFreq(&RCC_ClockFreq);
//----- IO initialization -----
gpioInit.GPIO_Pin = led1|led2|led3|led4;
gpioInit.GPIO_Mode = GPIO_Mode_Out_PP;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(led , &gpioInit); //initialiazate gpio
GPIO_SetBits(led , gpioInit.GPIO_Pin); //Set pin
//GPIO_ResetBits(led , gpioInit.GPIO_Pin); //Reset pin
// Configure USART1 Tx (PA.09) as alternate push-pull --------
gpioInit.GPIO_Pin = GPIO_Pin_9;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &gpioInit);
// Configure USART1 Tx (PA.10) as alternate push-pull --------
gpioInit.GPIO_Pin = GPIO_Pin_10;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &gpioInit);
//----- NVIC initialization -----
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 抢占式优先级别
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//指定中断源
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;// 指定响应优先级别1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//----- UART initialization ----
//0-----串口参数配置------
USART_InitStructure.USART_BaudRate = 19200; //设置波特率为19200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //设置数据位为8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //设置停止位为1位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //没有硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //send and receive mode
//0-----------------------
USART_Init(USART1, &USART_InitStructure); //initialization USART1
USART_Cmd(USART1 , ENABLE); //enable USART1 modulation
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //enable USART1 interruption
//查询方式发送数据
string = "www.hi.baidu.com/th152210\n";
GPIO_ResetBits(led , led1|led2); //Reset pin
putString(string,0); //send string
GPIO_SetBits(led , led1|led2); //Set pin
while(1)
{
}
}
STM32文件中的相关代码:
void USART1_IRQHandler(void)
{
if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除中断标志
USART_SendData(USART1 , USART_ReceiveData(USART1));
}
}
回复
有奖活动 | |
---|---|
【EEPW电子工程师创研计划】技术变现通道已开启~ | |
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
“我踩过的那些坑”主题活动——第001期 | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【我踩过的那些坑】电感选型错误导致的处理器连接不上被打赏50分 | |
【我踩过的那些坑】工作那些年踩过的记忆深刻的坑被打赏10分 | |
【我踩过的那些坑】DRC使用位置错误导致的问题被打赏100分 | |
我踩过的那些坑之混合OTL功放与落地音箱被打赏50分 | |
汽车电子中巡航控制系统的使用被打赏10分 | |
【我踩过的那些坑】工作那些年踩过的记忆深刻的坑被打赏100分 | |
分享汽车电子中巡航控制系统知识被打赏10分 | |
分享安全气囊系统的检修注意事项被打赏10分 | |
分享电子控制安全气囊计算机知识点被打赏10分 | |
【分享开发笔记,赚取电动螺丝刀】【OZONE】使用方法总结被打赏20分 |