例程一 推挽输出
LED.h
1 2 3 4 |
#ifndef __LED_H #define __LED_H void LED_Init(void); #endif |
led.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include "LED.h" #include "stm32f10x.h" void LED_Init(void){ // 定义结构体用于GPIO_Init函数,必须在第一行就定义否则会报错 GPIO_InitTypeDef GPIO_Structure; // 首先要使能时钟,注意不同IO组使能时钟的函数是不同的 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); // 初始化GPIOB PIN5的属性 GPIO_Structure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置为推挽输出 GPIO_Structure.GPIO_Pin = GPIO_Pin_5; GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_Structure); // 将其初始化为低电平输出 GPIO_SetBits(GPIOB, GPIO_Pin_5); // 初始化GPIOE PIN5的属性 GPIO_Structure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Structure.GPIO_Pin = GPIO_Pin_5; GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_Structure); // 将其初始化为低电平输出 GPIO_SetBits(GPIOB, GPIO_Pin_5); // 初始化GPIOB PIN5的属性 GPIO_Structure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置为推挽输出 GPIO_Structure.GPIO_Pin = GPIO_Pin_8; GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_Structure); // 将其初始化为低电平输出 GPIO_SetBits(GPIOB, GPIO_Pin_8); } |
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include "stm32f10x.h" #include "led.h" #include "delay.h" int main(void){ delay_init(); LED_Init(); // 初始化IO while(1){ GPIO_SetBits(GPIOB,GPIO_Pin_8); GPIO_SetBits(GPIOB,GPIO_Pin_5); GPIO_ResetBits(GPIOE, GPIO_Pin_5); delay_ms(500); GPIO_ResetBits(GPIOB, GPIO_Pin_5); GPIO_SetBits(GPIOE,GPIO_Pin_5); delay_ms(500); GPIO_ResetBits(GPIOB, GPIO_Pin_8); delay_ms(500); } } |
例程二 按键操作
KEY.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#ifndef __KEY_H #define __KEY_H #include "sys.h" #define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键0 #define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键1 #define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP) #define KEY0_PRES 1 // KEY0按下 #define KEY1_PRES 2 // KEY1 按下 #define WKUP_PRES 3 // KEY3 按下 void KEY_Init(void); // IO初始化 u8 KEY_Scan(u8); // 按键扫描函数 #endif |
key.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include "KEY.h" #include "delay.h" void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_3;//KEY0-KEY1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE4,3 //初始化 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 } //按键处理函数 //返回按键值 //mode:0,不支持连续按;1,支持连续按; //0,没有任何按键按下 //1,KEY0按下 //2,KEY1按下 //3,KEY3按下 WK_UP //注意此函数有响应优先级,KEY0>KEY1>KEY_UP!! u8 KEY_Scan(u8 mode) { static u8 key_up=1;//按键按松开标志 if(mode)key_up=1; //支持连按 if(key_up&&(KEY0==0||KEY1==0||WK_UP==1)) { delay_ms(10);//去抖动 key_up=0; if(KEY0==0)return KEY0_PRES; else if(KEY1==0)return KEY1_PRES; else if(WK_UP==1)return WKUP_PRES; }else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1; return 0;// 无按键按下 } |
LED.h
1 2 3 4 5 6 7 8 9 10 11 |
#ifndef __LED_H #define __LED_H #include "sys.h" // 定义位操作 #define LED0 PBout(5)// PB5 #define LED1 PEout(5)// PE5 void LED_Init(void); // 初始化 #endif |
led.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include "LED.h" void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); // 初始化PB5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_5); // 初始化PE5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_Init(GPIOE, &GPIO_InitStructure); GPIO_SetBits(GPIOE, GPIO_Pin_5); } |
BEEP.h
1 2 3 4 5 6 7 |
#ifndef __BEEP_H #define __BEEP_H #include "sys.h" #define BEEP PBout(8) void BEEP_Init(void); #endif |
beep.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include "BEEP.h" void BEEP_Init(void) { // 初始化GPIO结构体 GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOB的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIO端口的时钟 // 配置GPIO 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 // 初始化的时候就输出0 关闭蜂鸣器的输出 GPIO_ResetBits(GPIOB,GPIO_Pin_8);//输出0,关闭蜂鸣器输出 } |
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include "delay.h" #include "sys.h" #include "LED.h" #include "BEEP.h" #include "KEY.h" int main(void) { vu8 key = 0; LED_Init(); BEEP_Init(); KEY_Init(); //初始化与按键连接的硬件接口 delay_init(); LED0 = 0; // 先点亮红灯,输出低电平时点亮 while(1) { key = KEY_Scan(0); // 得到键值 // 如果按下了 if(key){ switch(key){ case WKUP_PRES: //控制蜂鸣器 BEEP=!BEEP; break; case KEY1_PRES: //控制LED1翻转 LED1=!LED1; break; case KEY0_PRES: //同时控制LED0,LED1翻转 LED0=!LED0; LED1=!LED1; break; } } } } |
例程三:USART通讯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include "stm32f10x.h" #include "delay.h" void My_USART_Init(void) { // 初始化结构体 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // 第一步:使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 使能串口时钟 // 第二步:初始化IO 通过查表得来 // A9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 设置位推挽复用输出 查表得 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // A10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 对于输入可以设置位浮空或者上拉输入 查表得 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 第三步:串口初始化 USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不适用硬件流 USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1个停止位 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 没有奇偶校验字长设置为8 USART_Init(USART1, &USART_InitStructure); // 第四步:串口1使能 USART_Cmd(USART1, ENABLE); // 第五步:设置中断 开启接收中断 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); // 初始化中断的成员变量 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 是否开启中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 设置抢占主优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 设置抢占子优先级 NVIC_Init(&NVIC_InitStructure); } // 中断服务函数 接收到数据就会执行这个中断 void USART1_IRQHandler(void) { u8 res; if(USART_GetITStatus(USART1, USART_IT_RXNE)) // 这里要判断一下是那个中断因为中断可能不只有一个 { res = USART_ReceiveData(USART1); // 这是接收到的数据 USART_SendData(USART1, res); // 接收到数据之后再把数据发送给串口 } } int main(void) { // 设置中断 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 将系统的中断优先级分组 设置两位抢占两位响应 My_USART_Init(); while(1); } |
例程四 解析JSON字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "usart.h" #include "cJSON.h" const char * my_json_string = "{\"device\":\"16\",\"class\":\"master\",\"call\":\"start\",\"ar1\":\"10\"}"; int main(void) { char * device; char * cls; char * call; char * arg1; u16 k; u16 len; u16 times=0; cJSON * root = cJSON_Parse(my_json_string); cJSON * dev = cJSON_GetObjectItem(root, "device"); cJSON * cla = cJSON_GetObjectItem(root, "class"); cJSON * cl = cJSON_GetObjectItem(root, "call"); cJSON * ar1 = cJSON_GetObjectItem(root, "ar1"); device = dev->valuestring; cls = cla->valuestring; call = cl->valuestring; arg1 = ar1->valuestring; 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(k=0;k<len;k++) { USART_SendData(USART1, USART_RX_BUF[k]);//向串口1发送数据 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束 } printf("\r\n\r\n");//插入换行 // 开始解析JSON printf("\r\nJSON消息为:\r\n\r\n"); printf("%s\r\n", device); printf("%s\r\n", cls); printf("%s\r\n", call); printf("%s\r\n", arg1); 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("\r\n请输入数据,以回车键结束\n"); if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行. delay_ms(10); } } } |