小言_互联网的博客

基于stm32 的简单的智慧农业系统, 有上位机,有下位机

1127人阅读  评论(0)

1. 实现的功能

1. 下位机(stm32) (keil 5 )

        1. 按键key1 中断控制 LED 3 的亮灭

        2. 按键key2  中断控制  温湿度的获取, (数据通过串口发送给 上位机)

        3. 智能检测温湿度是否超标, (超标 开启警报, 开启风扇)

        4.OLED  显示 温湿度,(每次获取温湿度,更新数据)

        5. 设置窗口看门狗, 保证程序不会出现异常, (中断喂狗)

2. 上位机

        1. 按钮1   通过串口通信控制 LED 3 的亮灭

        2. 按钮2   通过串口通信控制  蜂鸣器的开启与关闭 

        3. 按键3   通过 串口通信 获取温湿度的数据  

        4.  旋钮,通过 串口通信  调节 呼吸灯LED1 的亮度 (PWM 技术控制)


 2. 制作过程中遇到的问题

1. 串口通信的时候  下位机接收的 问题  ( 接收函数,判定数据正确的条件有一个 语句后面需要加 \r\n   )     之前的串口调试工具是自动加的,  所以我这里出现了问题。 

2. Dht11 温湿度传感器  的时序图的 解读有一点问题, 我之前以为获取数据是只要发送一次起始信号就可以无限获取数据,  但是程序的实验结果告诉我们, 发送一次起始数据, 判断一次 传感器的高低电平数据, 才可以接收一次数据,  而且我们的传感器启动的时候,需要停止  1秒 启动。

3. PWM 控制呼吸灯的时候,发现有程序控制的 LED 3  (比如说是中断),  不可以使用 PWM 的函数控制。  PWM  控制的LED   在主程序里面不可以被控制, 只能通过 PWM 的控制函数控制。

4.  在智能检测温湿度是否超标  的时候需要加一个特判 , 才能防止 超标代码对其他功能的妨碍.

5. OLED  的取模是一个  技术活。!!

6.每一个 程序的功能需要 单独测试 , 封装成函数更好!!


3.代码:  (板子不同,硬件的引脚可能不同,程序功能不同)

(板子   stm32 f407VET6 )

下位机: (自己写的 片上外设的控制 文件) (系统的文件自己找, )  (资源已经上传, 0积分 ))

 main.cpp 


  
  1. #include "BEEP.h"//蜂鸣器
  2. #include "KEY.h"//按键
  3. #include "LED.h"//LED
  4. #include "motor.h"// 电风扇
  5. #include "delay.h"//延时函数
  6. #include "myiic.h"//IIC
  7. #include "oled.h"//oled 屏幕显示
  8. #include "MyDht11.h"// 温湿度传感器
  9. #include "myusart.h"//串口通信
  10. #include "stdio.h"
  11. #include "PWM.h"//PWM 控制是灯光的亮度
  12. #include "wwdg.h"
  13. #include "misc.h"
  14. #include "stm32f4xx_exti.h"
  15. #include "MYEXIT.h"
  16. void oled_dht11_display(void); //把温度显示在oled上面
  17. void oled_display_x_y(int a,int b,char ff); //oled 屏幕字符显示
  18. void led_twinkle(void); // 第二个灯的闪烁
  19. void wanning_open(void); // 打开警报
  20. void wanning_close(void); //关闭警报
  21. //全局变量
  22. char a111,a222; //a111 湿度, a222 温度
  23. int main(void)
  24. {
  25. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置系统中断优先级分组2
  26. ledinit(); //LED 灯初始化
  27. key_init(); //按键初始化
  28. beepinit(); //蜂鸣器初始化0p
  29. motor_init(); // 电机初始化
  30. delay_init( 168); //延时初始化
  31. IIC_Init(); //IIC 初始化
  32. InitOLed(); //oled 初始化
  33. myusart_init( 115200); // 串口通信初始化
  34. DHT11_init(); //温湿度传感器初始化
  35. TIM14_PWM_Init(); //呼吸灯初始化
  36. wwdginit(); //窗口看门狗 初始化
  37. MYEXIT_init(); //中断初始化
  38. int len;
  39. int panduan= 0;
  40. while( 1)
  41. {
  42. if(a222> 26)
  43. {
  44. wanning_open();
  45. panduan= 1;
  46. }
  47. else
  48. {
  49. if(panduan== 1)
  50. {
  51. wanning_close();
  52. panduan= 0;
  53. }
  54. }
  55. if(USART_RX_STA& 0x8000)
  56. {
  57. len=USART_RX_STA& 0x3fff; //得到此次接收到的数据长度
  58. if(len <= 3)
  59. {
  60. int a1=( int)(USART_RX_BUF[ 0] -48);
  61. if(a1== 1) //开灯
  62. {
  63. select_led( 3);
  64. }
  65. if(a1== 2) //关灯
  66. {
  67. close_num_led( 3);
  68. }
  69. if(a1== 3) //开蜂鸣器
  70. {
  71. openBeep(); //打开蜂鸣器警报
  72. }
  73. if(a1== 4) //关闭蜂鸣器
  74. {
  75. closeBeep(); //关闭蜂鸣器
  76. }
  77. if(a1== 5)
  78. {
  79. oled_dht11_display();
  80. led_twinkle();
  81. }
  82. if(a1== 0)
  83. {
  84. if(len<= 3)
  85. {
  86. int a2=( int)(USART_RX_BUF[ 1] -48)* 10;
  87. int a3=( int)(USART_RX_BUF[ 2] -48);
  88. int a4=a2+a3;
  89. ppp(a4);
  90. }
  91. }
  92. }
  93. USART_RX_STA= 0;
  94. }
  95. }
  96. }
  97. void wanning_open()
  98. {
  99. openBeep(); //打开蜂鸣器警报
  100. motor_ON(); //打开 风扇电机
  101. }
  102. void wanning_close()
  103. {
  104. closeBeep(); //关闭蜂鸣器
  105. motor_OFF(); //关闭 风扇电机
  106. }
  107. void oled_display_x_y(int a,int b,char ff)
  108. {
  109. char nn = ff/ 10;
  110. char mm = ff% 10;
  111. if(nn== 0)
  112. {
  113. OLed_ShowASCII(a,b, "0"); //显示英文。
  114. }
  115. else if(nn== 1)
  116. {
  117. OLed_ShowASCII(a,b, "1"); //显示英文。
  118. }
  119. else if(nn== 2)
  120. {
  121. OLed_ShowASCII(a,b, "2"); //显示英文。
  122. }
  123. else if(nn== 3)
  124. {
  125. OLed_ShowASCII(a,b, "3"); //显示英文。
  126. }
  127. else if(nn== 4)
  128. {
  129. OLed_ShowASCII(a,b, "4"); //显示英文。
  130. }
  131. else if(nn== 5)
  132. {
  133. OLed_ShowASCII(a,b, "5"); //显示英文。
  134. }
  135. else if(nn== 6)
  136. {
  137. OLed_ShowASCII(a,b, "6"); //显示英文。
  138. }
  139. else if(nn== 7)
  140. {
  141. OLed_ShowASCII(a,b, "7"); //显示英文。
  142. }
  143. else if(nn== 8)
  144. {
  145. OLed_ShowASCII(a,b, "8"); //显示英文。
  146. }
  147. else if(nn== 9)
  148. {
  149. OLed_ShowASCII(a,b, "9"); //显示英文。
  150. }
  151. if(mm== 0)
  152. {
  153. OLed_ShowASCII(a+ 8,b, "0"); //显示英文。
  154. }
  155. else if(mm== 1)
  156. {
  157. OLed_ShowASCII(a+ 8,b, "1"); //显示英文。
  158. }
  159. else if(mm== 2)
  160. {
  161. OLed_ShowASCII(a+ 8,b, "2"); //显示英文。
  162. }
  163. else if(mm== 3)
  164. {
  165. OLed_ShowASCII(a+ 8,b, "3"); //显示英文。
  166. }
  167. else if(mm== 4)
  168. {
  169. OLed_ShowASCII(a+ 8,b, "4"); //显示英文。
  170. }
  171. else if(mm== 5)
  172. {
  173. OLed_ShowASCII(a+ 8,b, "5"); //显示英文。
  174. }
  175. else if(mm== 6)
  176. {
  177. OLed_ShowASCII(a+ 8,b, "6"); //显示英文。
  178. }
  179. else if(mm== 7)
  180. {
  181. OLed_ShowASCII(a+ 8,b, "7"); //显示英文。
  182. }
  183. else if(mm== 8)
  184. {
  185. OLed_ShowASCII(a+ 8,b, "8"); //显示英文。
  186. }
  187. else if(mm== 9)
  188. {
  189. OLed_ShowASCII(a+ 8,b, "9"); //显示英文。
  190. }
  191. }
  192. void oled_dht11_display()//把温度显示在oled上面
  193. {
  194. OLed_ShowChina( 0, 0,HZ4);
  195. OLed_ShowChina( 16, 0,HZ5);
  196. OLed_ShowChina( 32, 0,HZ6);
  197. OLed_ShowChina( 48, 0,HZ7);
  198. OLed_ShowChina( 64, 0,HZ8);
  199. OLed_ShowChina( 80, 0,HZ9);
  200. OLed_ShowChina( 96, 0,HZ10);
  201. OLed_ShowChina( 112, 0,HZ11);
  202. if( DHT11_ReadData(&a111,&a222)== 0)
  203. {
  204. delay_ms( 1000);
  205. //printt("oled ",a111);
  206. printt( "oled ",a222);
  207. }
  208. OLed_ShowChina( 0, 2,HZ1);
  209. OLed_ShowChina( 16, 2,HZ2);
  210. oled_display_x_y( 48, 2,a222);
  211. OLed_ShowChina( 64, 2,HZ2);
  212. //第2行显示湿度
  213. OLed_ShowChina( 0, 4,HZ3);
  214. OLed_ShowChina( 16, 4,HZ2);
  215. oled_display_x_y( 48, 4,a111);
  216. OLed_ShowASCII( 64, 4, "%");
  217. }
  218. void led_twinkle(void)//第二个灯的闪烁
  219. {
  220. int i;
  221. int k= 0;
  222. if( GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_9)== 1) // 记录现在的状态
  223. {
  224. k= 1;
  225. }
  226. else
  227. {
  228. k= 2;
  229. }
  230. //闪烁
  231. for(i= 0;i< 5;i++)
  232. {
  233. select_led( 2);
  234. delay_ms( 100);
  235. close_num_led( 2);
  236. delay_ms( 100);
  237. }
  238. //还原原来的状态
  239. if(k== 1)
  240. {
  241. close_num_led( 2);
  242. }
  243. else if(k== 2)
  244. {
  245. select_led( 2);
  246. }
  247. }
  248. void EXTI9_5_IRQHandler(void)
  249. {
  250. if( EXTI_GetITStatus(EXTI_Line5) != RESET) //按下KEY2
  251. {
  252. oled_dht11_display();
  253. led_twinkle();
  254. EXTI_ClearITPendingBit(EXTI_Line5);
  255. }
  256. //else if(EXTI_GetITStatus(EXTI_Line6) != RESET) //按下KEY3
  257. //{
  258. // EXTI_ClearITPendingBit(EXTI_Line6);
  259. //}
  260. }

1. BEEP .h 


  
  1. #ifndef __BEEP_H__
  2. #define __BEEP_H__
  3. void beepinit(void); //初始化
  4. void openBeep(void); //打开蜂鸣器
  5. void closeBeep(void); //关闭蜂鸣器
  6. #endif

2.BEEP.c


  
  1. #include "stm32f4xx.h" //头文件
  2. #include "stm32f4xx_gpio.h"
  3. #include "stm32f4xx_rcc.h"
  4. #include "beep.h"
  5. void beepinit(void)
  6. {
  7. //1.时钟问题解决
  8. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //
  9. //2.引脚配置问题解决
  10. GPIO_InitTypeDef beepstruct; //设置变量
  11. beepstruct.GPIO_Mode= GPIO_Mode_OUT; //输出模式 //引脚输出信号
  12. beepstruct.GPIO_OType=GPIO_OType_PP; //外部无上拉电阻选择推挽输出, 外部有上拉电阻选择开漏输出
  13. beepstruct.GPIO_Pin=GPIO_Pin_10; //引脚的编号是哪个
  14. beepstruct.GPIO_PuPd=GPIO_PuPd_UP; //上拉电阻
  15. beepstruct.GPIO_Speed=GPIO_Low_Speed; //配置速度
  16. GPIO_Init(GPIOB,&beepstruct);
  17. //3.初始化
  18. GPIO_ResetBits(GPIOB,GPIO_Pin_10); //设置输出低电平 ,开始的时候让他不响
  19. }
  20. void openBeep(void)//打开蜂鸣器
  21. {
  22. //GPIO_WriteBit(GPIOB,GPIO_Pin_10,Bit_SET);//打开蜂鸣器
  23. GPIO_SetBits(GPIOB,GPIO_Pin_10); //打开蜂鸣器
  24. }
  25. void closeBeep(void)//关闭蜂鸣器
  26. {
  27. //GPIO_WriteBit(GPIOB,GPIO_Pin_10,Bit_RESET);//关闭蜂鸣器
  28. GPIO_ResetBits(GPIOB,GPIO_Pin_10); //设置输出低电平 ,开始的时候让他不响
  29. }

  3.KEY.h 


  
  1. #ifndef __KEY_H__
  2. #define __KEY_H__
  3. #include "stm32f4xx_gpio.h"
  4. #include "stm32f4xx_rcc.h"
  5. void key_init(void); //初始化key
  6. int key_youxi(void); //key 按键的游戏
  7. #endif

4.KEY.c


  
  1. #include "stm32f4xx.h" //头文件
  2. #include "stm32f4xx_gpio.h"
  3. #include "stm32f4xx_rcc.h"
  4. #include "key.h"
  5. void key_init(void)//初始化key
  6. {
  7. //初始key1 key2 key3
  8. //1.时钟问题解决
  9. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
  10. GPIO_InitTypeDef keystruct; //设置变量
  11. keystruct.GPIO_Mode=GPIO_Mode_IN; //输入模式 //引脚输入信号
  12. keystruct.GPIO_Pin=GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6; // 三个按键一起初始化
  13. //keystruct.GPIO_OType 输出类型不需要
  14. keystruct.GPIO_PuPd=GPIO_PuPd_UP; //需要上拉电阻
  15. keystruct.GPIO_Speed=GPIO_Low_Speed; //速度
  16. GPIO_Init(GPIOE,&keystruct);
  17. //初始化
  18. GPIO_SetBits(GPIOE,GPIO_Pin_4|GPIO_Pin_5 |GPIO_Pin_6); //给这些按键高电平 key1 key2 key3
  19. //初始化 key4
  20. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
  21. GPIO_InitTypeDef keystruct1; //设置变量
  22. keystruct1.GPIO_Mode=GPIO_Mode_IN; //输入模式 //引脚输入信号
  23. keystruct1.GPIO_Pin=GPIO_Pin_13; // 按键一起初始化
  24. //keystruct.GPIO_OType 输出类型不需要
  25. keystruct1.GPIO_PuPd=GPIO_PuPd_UP; //需要上拉电阻
  26. keystruct1.GPIO_Speed=GPIO_Low_Speed; //速度
  27. GPIO_Init(GPIOC,&keystruct1);
  28. GPIO_SetBits(GPIOC,GPIO_Pin_13); //给这些按键高电平 key4
  29. }
  30. int key_youxi(void)//key 按键的游戏
  31. {
  32. int i;
  33. if(! GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)) //这个函数是高电平返回 1 低电平 返回 0
  34. {
  35. for(i= 10000;i> 0;i--); //消抖
  36. if(! GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4))
  37. {
  38. while( GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)== 0);
  39. return 1;
  40. }
  41. }
  42. if(! GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_5)) //这个函数是高电平返回 1 低电平 返回 0
  43. {
  44. for(i= 10000;i> 0;i--); //消抖
  45. if(! GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_5))
  46. {
  47. while( GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_5)== 0);
  48. return 2;
  49. }
  50. }
  51. if(! GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_6)) //这个函数是高电平返回 1 低电平 返回 0
  52. {
  53. for(i= 10000;i> 0;i--); //消抖
  54. if(! GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_6))
  55. {
  56. while( GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_6)== 0);
  57. return 3;
  58. }
  59. }
  60. if(! GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)) //这个函数是高电平返回 1 低电平 返回 0
  61. {
  62. for(i= 10000;i> 0;i--); //消抖
  63. if(! GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13))
  64. {
  65. while( GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)== 0);
  66. return 4;
  67. }
  68. }
  69. return 0;
  70. }

5. LED.h


  
  1. #ifndef __LED_H__
  2. #define __LED_H__
  3. #include "stm32f4xx_gpio.h"
  4. #include "stm32f4xx_rcc.h"
  5. void delay(void); // for 延时
  6. void ledinit(void); //初始化
  7. void select_led(int a); //假如a != 1 2 3 ,就关闭所有的灯
  8. void liushui_led(void); // 展示流水灯的程序
  9. void close_led(void ); //关闭所有的小灯
  10. void close_num_led(int a); //关闭指定的小灯
  11. #endif

6. LED.c


  
  1. #include "stm32f4xx.h" //头文件
  2. #include "stm32f4xx_gpio.h"
  3. #include "stm32f4xx_rcc.h"
  4. #include "led.h"
  5. void delay()//延时函数
  6. {
  7. int b= 5000000;
  8. while(b--) //形成延时函数
  9. {
  10. }
  11. }
  12. void ledinit()
  13. {
  14. //led 低电平驱动
  15. //3 个led 可控制,一个不可控制
  16. //二极管单向导通,阳极固定高电平,阴极输出高电平,led 灭
  17. //二极管单向导通,阳极固定高电平,阴极输出低电平,led 亮
  18. GPIO_InitTypeDef GIOSTRUCT;
  19. //1.配置时钟: 给个心跳。 选择需要的时钟频率
  20. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
  21. //2.配置功能: 功能太多。 选择GPIO功能;
  22. GIOSTRUCT.GPIO_Mode=GPIO_Mode_OUT ; //输出模式 //引脚输出信号
  23. GIOSTRUCT.GPIO_Pin=GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10; //led 灯的引脚
  24. GIOSTRUCT.GPIO_PuPd=GPIO_PuPd_UP; //上拉电阻
  25. GIOSTRUCT.GPIO_Speed=GPIO_Low_Speed; //配置速度
  26. //外部无上拉电阻选择推挽输出, 外部有上拉电阻选择开漏输出
  27. GIOSTRUCT.GPIO_OType=GPIO_OType_PP;
  28. GPIO_Init(GPIOE,&GIOSTRUCT);
  29. //GPIO_Init(GPIOE,&GIOSTRUCT);
  30. //3.操作引脚: 输出低电平 led 亮, 输出高电平 led灭
  31. //初始化
  32. GPIO_SetBits(GPIOE,GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 ); //把灯都关了
  33. //GPIO_ResetBits 输出低电平
  34. //GPIO_SetBits 输出高电平
  35. }
  36. void select_led(int a)//假如a != 1 2 3 ,就关闭所有的灯
  37. {
  38. if(a== 1)
  39. {
  40. GPIO_ResetBits(GPIOE,GPIO_Pin_8); //串口组, 引脚//打开第一个灯
  41. }
  42. if(a== 2)
  43. {
  44. GPIO_ResetBits(GPIOE,GPIO_Pin_9); //串口组, 引脚//打开第二个灯
  45. }
  46. if(a== 3)
  47. {
  48. GPIO_ResetBits(GPIOE,GPIO_Pin_10); //串口组, 引脚//打开第三个灯
  49. }
  50. }
  51. void close_num_led(int a)//关闭指定的小灯
  52. {
  53. if(a== 1)
  54. {
  55. GPIO_SetBits(GPIOE,GPIO_Pin_8 ); //把灯都关了
  56. }
  57. if(a== 2)
  58. {
  59. GPIO_SetBits(GPIOE,GPIO_Pin_9); //把灯都关了
  60. }
  61. if(a== 3)
  62. {
  63. GPIO_SetBits(GPIOE,GPIO_Pin_10 ); //把灯都关了
  64. }
  65. }
  66. void close_led(void )//关闭所有的小灯
  67. {
  68. GPIO_SetBits(GPIOE,GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 ); //把灯都关了
  69. }
  70. void liushui_led()//流水灯 , 功能: 从第一个灯 轮流闪烁 一直到最后一个灯,最后把所有的灯关闭。
  71. {
  72. GPIO_SetBits(GPIOE,GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 ); //把灯都关了
  73. GPIO_ResetBits(GPIOE,GPIO_Pin_8); //串口组, 引脚//打开第一个灯
  74. delay();
  75. GPIO_SetBits(GPIOE,GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 ); //把灯都关了
  76. GPIO_ResetBits(GPIOE,GPIO_Pin_9); //串口组, 引脚//打开第二个灯
  77. delay();
  78. GPIO_SetBits(GPIOE,GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 ); //把灯都关了
  79. GPIO_ResetBits(GPIOE,GPIO_Pin_10); //串口组, 引脚//打开第三个灯
  80. delay();
  81. GPIO_SetBits(GPIOE,GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 ); //把灯都关了
  82. }

7. motor.h


  
  1. #ifndef __MOTOR_H__
  2. #define __MOTOR_H__
  3. void motor_init(void); //风扇初始化
  4. #define motor_ON() GPIO_SetBits(GPIOB,GPIO_Pin_15);//给e组的8个引脚低电平
  5. #define motor_OFF() GPIO_ResetBits(GPIOB,GPIO_Pin_15);//给e组的8个引脚低电平
  6. // 请按下按键2 让第三个灯亮和灭
  7. #endif

8.motor.c


  
  1. #include "motor.h"
  2. #include "stm32f4xx.h"
  3. #include "stm32f4xx_gpio.h"
  4. #include "stm32f4xx_rcc.h"
  5. void motor_init(void)
  6. {
  7. GPIO_InitTypeDef GPIO_InitStruct ;
  8. //第一步:AHB1总线上的E组引脚时钟使能;(心脏开始跳动)
  9. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
  10. //设置gpio结构体
  11. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15 ; //控制哪一个引脚 PE8
  12. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; // 设置引脚为输出
  13. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //设置输出速度
  14. GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽方式
  15. GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //设置高电平还是低电平
  16. //设置GPIO口寄存器数据
  17. GPIO_Init(GPIOB,&GPIO_InitStruct);
  18. GPIO_ResetBits(GPIOB,GPIO_Pin_15); //关闭电机
  19. }

9. MyDht11.h


  
  1. #ifndef __MYDHT11_H__
  2. #define __MYDHT11_H__
  3. #include "stm32f4xx.h"
  4. void DHT11_init(void); //初始化
  5. void DHT11_InMode(void); //模式变为 输入模式
  6. void DHT11_OutMode(void); // 模式变为 输出模式
  7. unsigned char DHT11_Read_Bit(void); //获取一位的 u8 数据
  8. unsigned char DHT11_ReadData(char * humi,char *temp); //获取 5 个u8 数据, 进行校验和
  9. void dht11_play_data(void); //输出数据
  10. #endif

10. MyDht11.c


  
  1. #include "MyDht11.h"
  2. #include "stm32f4xx.h"
  3. #include "delay.h"
  4. #include "myusart.h"
  5. char buff[ 5] = "";
  6. char humi = 0 ,temp = 0 ;
  7. char flg = 100 ,flg1 = 100;
  8. //读出来的数据是16进制也没事。把二进制发送上位机也没事。只要是一个字节就行。
  9. //引脚:PA3
  10. void DHT11_init()
  11. {
  12. //1,配置时钟
  13. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
  14. //2.配置引脚
  15. GPIO_InitTypeDef DHT11struct;
  16. //填写引脚
  17. DHT11struct.GPIO_Pin = GPIO_Pin_3;
  18. //填写速度
  19. DHT11struct.GPIO_Speed = GPIO_Speed_2MHz;
  20. DHT11struct.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  21. //填写电阻
  22. DHT11struct.GPIO_Mode = GPIO_Mode_OUT;
  23. //即可以输出高电平也可以输出低电平
  24. DHT11struct.GPIO_OType = GPIO_OType_OD;
  25. GPIO_Init(GPIOA,&DHT11struct);
  26. //把引脚拉高。
  27. GPIO_SetBits(GPIOA,GPIO_Pin_3);
  28. }
  29. //输入模式函数
  30. void DHT11_InMode()
  31. {
  32. //配置引脚
  33. GPIO_InitTypeDef DHT11struct;
  34. //填写引脚
  35. DHT11struct.GPIO_Pin = GPIO_Pin_3;
  36. //填写速度
  37. DHT11struct.GPIO_Speed = GPIO_Speed_2MHz;
  38. //填写电阻
  39. DHT11struct.GPIO_Mode = GPIO_Mode_IN;
  40. DHT11struct.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  41. //即可以输出高电平也可以输出低电平
  42. GPIO_Init(GPIOA,&DHT11struct);
  43. }
  44. //输入模式函数
  45. void DHT11_OutMode()
  46. {
  47. //配置引脚
  48. GPIO_InitTypeDef DHT11struct;
  49. //填写引脚
  50. DHT11struct.GPIO_Pin = GPIO_Pin_3;
  51. //填写速度
  52. DHT11struct.GPIO_Speed = GPIO_Speed_2MHz;
  53. //填写电阻
  54. //即可以输出高电平也可以输出低电平
  55. DHT11struct.GPIO_OType = GPIO_OType_OD;
  56. DHT11struct.GPIO_Mode = GPIO_Mode_OUT;
  57. DHT11struct.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  58. GPIO_Init(GPIOA,&DHT11struct);
  59. GPIO_SetBits(GPIOA,GPIO_Pin_3);
  60. }
  61. unsigned char DHT11_Read_Bit()
  62. {
  63. unsigned char readbit = 0 ;
  64. unsigned int i = 0 ;
  65. for(i = 0 ; i < 8 ; i++)
  66. {
  67. //为了避免最高位被移出去。
  68. readbit = readbit << 1 ;
  69. //1在内部也要等待高电平结束。因为在循环过程中,有高电平的持续时间。
  70. //高电平是上一个周期的数据
  71. while( GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3));
  72. //2等待引脚变为高电平,如果是低电平就卡主,等低电平结束
  73. while(! GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3));
  74. //如果是高电平持续30us
  75. //这里是读位数据。
  76. //如果高电平持续时间较长,也就是30us之后还是高电平
  77. if( GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3))
  78. {
  79. //如果读到的是高电平并且 50us以后又读一次还是高电平。
  80. delay_us( 30);
  81. }
  82. //又读一次还是高电平,那么久写数据1,否则就是低电平。
  83. if( GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3))
  84. readbit |= 1 ;
  85. else
  86. readbit |= 0 ;
  87. }
  88. return readbit;
  89. }
  90. unsigned char DHT11_ReadData(char * humi,char *temp)
  91. {
  92. unsigned char num = 0 ;
  93. unsigned int i = 0 ;
  94. //1.主机发送开始信号20ms,低电平20ms。至少拉低。
  95. GPIO_ResetBits(GPIOA,GPIO_Pin_3);
  96. delay_ms( 20);
  97. //2.主机拉高30us
  98. GPIO_SetBits(GPIOA,GPIO_Pin_3);
  99. delay_us( 30);
  100. DHT11_InMode();
  101. //如果发过来的是高电平,就等待高电平结束。
  102. //因为外拉电阻,如果读到的是高电平,就等待高电平结束。
  103. while( GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3));
  104. //3如果读到的是低电平,那么就等待低电平结束。
  105. while(! GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3))
  106. {
  107. //响应信号
  108. flg = 0xee ;
  109. }
  110. //4等待高电平结束。高点平持续时间太久也不行。
  111. while( GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3))
  112. { //如果低电平持续的时间太长,那么也要退出。
  113. delay_us( 4);
  114. num++;
  115. if(num > 20)
  116. return 1;
  117. }
  118. //高电平一旦结束,那么就是信号来了。
  119. //开始读数据
  120. // buff[0] = DHT11_Read_Bit();
  121. // buff[1] = DHT11_Read_Bit();
  122. // buff[2] = DHT11_Read_Bit();
  123. // buff[3] = DHT11_Read_Bit();
  124. // buff[4] = DHT11_Read_Bit();
  125. for(i = 0 ; i < 5 ; i++)
  126. {
  127. //读五次数据,五个字节。
  128. buff[i] = DHT11_Read_Bit();
  129. }
  130. //函数结束以后要把引脚调整为输出模式
  131. DHT11_OutMode();
  132. //5.校验数据
  133. if(buff[ 4] == buff[ 0] + buff[ 1] + buff[ 2] + buff[ 3] )
  134. {
  135. *humi = buff[ 0];
  136. *temp = buff[ 2] ;
  137. i = 0 ;
  138. return 0;
  139. }
  140. else
  141. return 1 ;
  142. }
  143. void dht11_play_data(void)
  144. {
  145. char a1,a2;
  146. if( DHT11_ReadData(&a1,&a2)== 0)
  147. {
  148. delay_ms( 1000);
  149. printt( "湿度是:",a1);
  150. printt( "温度是:",a2);
  151. }
  152. }

11.MYEXIT.h 


  
  1. #ifndef __MYEXIT_H__
  2. #define __MYEXIT_H__
  3. void MYEXIT_init(void); //初始化
  4. #endif

12.MYEXIT.c


  
  1. #include "MYEXIT.h"
  2. #include "stm32f4xx.h" //头文件
  3. #include "stm32f4xx_rcc.h"
  4. #include "stm32f4xx_gpio.h"
  5. #include "KEY.h"
  6. #include "LED.h"
  7. #include "delay.h"
  8. #include "MyDht11.h"
  9. void MYEXIT_init(void)//初始化
  10. {
  11. EXTI_InitTypeDef EXTI_InitStructure;
  12. NVIC_InitTypeDef NVIC_InitStruct;
  13. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); //中断使能
  14. //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分组
  15. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource4); //绑定端口
  16. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource5); //绑定端口
  17. EXTI_InitStructure.EXTI_Line = EXTI_Line5 | EXTI_Line4 ; //那根中断线
  18. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置中断和事件
  19. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
  20. EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断使能
  21. EXTI_Init(&EXTI_InitStructure);
  22. NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn;
  23. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //设置抢占优先级
  24. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //设置响应优先级
  25. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
  26. NVIC_Init(&NVIC_InitStruct);
  27. NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
  28. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //设置抢占优先级
  29. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; //设置响应优先级
  30. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
  31. NVIC_Init(&NVIC_InitStruct);
  32. }
  33. void EXTI4_IRQHandler(void)
  34. {
  35. static int LED= 1;
  36. delay_ms( 20);
  37. if( key_youxi()== 1)
  38. {
  39. if(LED% 2== 1)
  40. {
  41. select_led( 3);
  42. LED= 0;
  43. }
  44. else if(LED% 2== 0)
  45. {
  46. close_num_led( 3);
  47. LED= 1;
  48. }
  49. }
  50. EXTI_ClearITPendingBit(EXTI_Line4);
  51. }

13.myiic.h


  
  1. #ifndef __MY_I2C_H__
  2. #define __MY_I2C_H__
  3. #include "stm32f4xx .h"
  4. #define SCL_HIGH() GPIO_SetBits(GPIOB,GPIO_Pin_6) //不能有空格,以免宏展开错误
  5. #define SCL_LOW() GPIO_ResetBits(GPIOB,GPIO_Pin_6)
  6. #define SDA_HIGH() GPIO_SetBits(GPIOB,GPIO_Pin_7)
  7. #define SDA_LOW() GPIO_ResetBits(GPIOB,GPIO_Pin_7)
  8. u8 IIC_Read_Byte(unsigned char ack);
  9. void IIC_Send_Byte(u8 txd);
  10. void IIC_NAck(void);
  11. void IIC_Ack(void);
  12. u8 IIC_Wait_Ack(void);
  13. void IIC_Stop(void);
  14. void IIC_Start(void);
  15. void IIC_Init(void);
  16. u8 READ_SDA(void);
  17. void SDA_OUT(void);
  18. void SDA_IN(void);
  19. #endif

14. myiic.c


  
  1. #include "myiic.h"
  2. #include "delay.h"
  3. #define I2C_DELAY 8
  4. void SDA_OUT(void)
  5. {
  6. GPIO_InitTypeDef GPIO_InitStructure;
  7. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  9. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  11. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  12. GPIO_Init(GPIOB,&GPIO_InitStructure);
  13. }
  14. void SDA_IN(void)
  15. {
  16. GPIO_InitTypeDef GPIO_InitStructure;
  17. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  18. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  19. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  21. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  22. GPIO_Init(GPIOB,&GPIO_InitStructure);
  23. }
  24. /*
  25. //初始化IIC
  26. I2C_SCL ---> PB6
  27. I2C_SDA ---> PB7
  28. */
  29. //1.初始化函数
  30. void IIC_Init(void)
  31. {
  32. GPIO_InitTypeDef GPIO_InitStructure;
  33. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能GPIOB时钟
  34. //GPIOB6,B7初始化设置
  35. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  36. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式
  37. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
  38. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
  39. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
  40. GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化
  41. //B组第6个引脚高电平 空闲状态
  42. //SCL_HIGH();
  43. SCL_HIGH();
  44. //B组第7个引脚高电平
  45. //SDA_HIGH();
  46. SDA_HIGH();
  47. }
  48. //2开始信号函数 ok
  49. void IIC_Start(void)
  50. {
  51. //B组第7个引脚设定成输出模式
  52. SDA_OUT();
  53. //两个都是输出高电平
  54. SDA_HIGH();
  55. SCL_HIGH();
  56. //延时2微秒
  57. delay_us(I2C_DELAY);
  58. //数据线由高电平变成低电平
  59. //START:when CLK is high,DATA change form high to low
  60. SDA_LOW();
  61. //再延时2微秒
  62. delay_us(I2C_DELAY);
  63. //把时钟线也拉低
  64. SCL_LOW();
  65. }
  66. //3产生IIC停止信号
  67. //STOP:when CLK is high DATA change form low to high
  68. void IIC_Stop(void)
  69. {
  70. //B组第7个引脚数据线设定成输出模式
  71. SDA_OUT();
  72. //两个都输出低电平。
  73. SCL_LOW();
  74. SDA_LOW();
  75. delay_us(I2C_DELAY);
  76. //clk时钟线先跳到高电平。
  77. SCL_HIGH();
  78. delay_us(I2C_DELAY);
  79. //数据线再由低电平跳变到高电平。
  80. SDA_HIGH();
  81. delay_us(I2C_DELAY);
  82. }
  83. //等待应答信号到来
  84. //返回值:1,接收应答失败
  85. // 0,接收应答成功
  86. u8 IIC_Wait_Ack(void)
  87. {
  88. u8 ucErrTime= 0;
  89. //将PB第7个引脚设定成输入模式,等待读取数据
  90. SDA_IN();
  91. //数据线高电平
  92. SDA_HIGH();
  93. delay_us(I2C_DELAY);
  94. //时钟线高电平
  95. SCL_HIGH();
  96. delay_us(I2C_DELAY);
  97. //数据线和时钟线两个都是高电平
  98. //等待对面的从设备把数据线拉低。
  99. //然后就等待,while有等待的意思,读取第7个引脚的数据。
  100. while( READ_SDA())
  101. {
  102. ucErrTime++;
  103. if(ucErrTime> 250)
  104. {
  105. IIC_Stop();
  106. return 1;
  107. }
  108. }
  109. //时钟输出0
  110. SCL_LOW();
  111. return 0;
  112. }
  113. //产生ACK应答
  114. //第9个时钟周期调用这个函数
  115. void IIC_Ack(void)
  116. {
  117. //低电平期间
  118. SCL_LOW();
  119. //数据线设定成输出模式
  120. SDA_OUT();
  121. //输出低电平 数据线始终为低电平
  122. SDA_LOW();
  123. //延时一定时间
  124. delay_us(I2C_DELAY);
  125. //输出高电平,并且稳定
  126. SCL_HIGH();
  127. delay_us(I2C_DELAY);
  128. //时钟线又跳到低电平:后续的电平可以变化
  129. SCL_LOW();
  130. }
  131. //不产生ACK应答
  132. void IIC_NAck(void)
  133. {
  134. //时钟线为低电平
  135. SCL_LOW() ;
  136. //设定数据线为输出模式
  137. SDA_OUT();
  138. //输出高电平 : 数据线始终为高电平
  139. SDA_HIGH();
  140. delay_us(I2C_DELAY);
  141. //时钟线跳变到高电平
  142. SCL_HIGH();
  143. delay_us(I2C_DELAY);
  144. //把时钟线拉低
  145. SCL_LOW() ;
  146. }
  147. //IIC发送一个字节
  148. //返回从机有无应答
  149. //1,有应答
  150. //0,无应答
  151. void IIC_Send_Byte(u8 txd) //1111 1111 & 1000 0000
  152. {
  153. u8 t;
  154. //设定数据线为输出模式
  155. SDA_OUT();
  156. //拉低时钟开始数据传输
  157. SCL_LOW() ;
  158. for(t= 0;t< 8;t++)
  159. {
  160. //取出数据的最高位 右移7位,然后发送出去
  161. if(txd & 0x80)
  162. SDA_HIGH();
  163. else
  164. SDA_LOW();
  165. //一个自己的数据左移一位,取出最高位
  166. txd<<= 1;
  167. //对TEA5767这三个延时都是必须的
  168. delay_us(I2C_DELAY);
  169. //高电平区间数据稳定
  170. SCL_HIGH();
  171. delay_us(I2C_DELAY);
  172. //低电平期间,数据线数据可以变化
  173. SCL_LOW() ;
  174. delay_us(I2C_DELAY);
  175. }
  176. }
  177. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  178. u8 IIC_Read_Byte(unsigned char ack)
  179. {
  180. unsigned char i,receive= 0;
  181. //SDA设置为输入,数据线设定为输入模式
  182. SDA_IN();
  183. //循环读数据
  184. for(i= 0;i< 8;i++ )
  185. {
  186. //时钟线为低电平
  187. SCL_LOW() ;
  188. delay_us(I2C_DELAY);
  189. //时钟线拉高
  190. SCL_HIGH();
  191. delay_us(I2C_DELAY);
  192. //时钟线为高电平的时候,读数据
  193. receive<<= 1; //receive是读到的是二进制数值
  194. if( READ_SDA()== 1) //如果读到了数据就把receive++,
  195. receive++; //读的是二进制数值
  196. }
  197. if (!ack)
  198. IIC_NAck(); //发送nACK
  199. else
  200. IIC_Ack(); //发送ACK
  201. return receive;
  202. }
  203. u8 READ_SDA(void)
  204. {
  205. u8 sda_val= 0;
  206. sda_val= GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7);
  207. return sda_val;
  208. }

15.oled.h


  
  1. #ifndef __OLED_H__
  2. #define __OLED_H__
  3. #include "stm32f4xx.h"
  4. //#include "sys.h"
  5. /*
  6. OLED 屏 --I2C接口
  7. slave addr: 0x3C ,低7位
  8. */
  9. #define OLED_SLAVE_ADDR_WR (0x3C<<1) //从机地址 011 11000
  10. extern uint8_t HZ1[]; //湿
  11. extern uint8_t HZ2[]; //温
  12. extern uint8_t HZ3[]; //度
  13. extern uint8_t HZ4[]; // 欢
  14. extern uint8_t HZ5[]; //迎
  15. extern uint8_t HZ6[]; //来
  16. extern uint8_t HZ7[]; //到
  17. extern uint8_t HZ8[]; // 智
  18. extern uint8_t HZ9[]; //慧
  19. extern uint8_t HZ10[]; //农
  20. extern uint8_t HZ11[]; //业
  21. //打开oled函数:初始化函数
  22. void InitOLed(void);
  23. //填充像素函数
  24. void OLed_Fill(uint8_t bmp_data);
  25. //显示字母函数
  26. void OLed_ShowASCII(uint8_t x, uint8_t y,char *str);
  27. //显示汉字函数
  28. void OLed_ShowChina(uint8_t x,uint8_t y,uint8_t *buf);
  29. //测试函数
  30. void OLed_ShowTest(uint8_t x,uint8_t y);
  31. //关闭oled函数
  32. void offInitOLed(void);
  33. //显示温度湿度
  34. void OLed_ShowTemp(void);
  35. #endif

16.oled.c


  
  1. #include "stm32f4xx.h" //系统库文件
  2. #include "oled.h" //oled操作函数文件
  3. #include "myiic.h" //iic接口文件;
  4. //======================================================
  5. // 128X64I液晶底层驱动[8X16]字体库
  6. // 设计者: powerint
  7. // 描 述: [8X16]西文字符的字模数据 (纵向取模,字节倒序)
  8. // !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
  9. //======================================================
  10. const unsigned char F8X16[]=
  11. {
  12. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
  13. 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //!1
  14. 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //"2
  15. 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, //#3
  16. 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$4
  17. 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //%5
  18. 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //&6
  19. 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //'7
  20. 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //(8
  21. 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //)9
  22. 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //*10
  23. 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+11
  24. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //,12
  25. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //-13
  26. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //.14
  27. 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, ///15
  28. 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, //016
  29. 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //117
  30. 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, //218
  31. 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //319
  32. 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, //420
  33. 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, //521
  34. 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //622
  35. 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, //723
  36. 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, //824
  37. 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, //925
  38. 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //:26
  39. 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //;27
  40. 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //<28
  41. 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //=29
  42. 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //>30
  43. 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //?31
  44. 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@32
  45. 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, //A33
  46. 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //B34
  47. 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, //C35
  48. 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //D36
  49. 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, //E37
  50. 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, //F38
  51. 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, //G39
  52. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, //H40
  53. 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //I41
  54. 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, //J42
  55. 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, //K43
  56. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, //L44
  57. 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, //M45
  58. 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, //N46
  59. 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //O47
  60. 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, //P48
  61. 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, //Q49
  62. 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, //R50
  63. 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, //S51
  64. 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //T52
  65. 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //U53
  66. 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, //V54
  67. 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, //W55
  68. 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, //X56
  69. 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //Y57
  70. 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, //Z58
  71. 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[59
  72. 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\60
  73. 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //]61
  74. 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^62
  75. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_63
  76. 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //`64
  77. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, //a65
  78. 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //b66
  79. 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, //c67
  80. 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, //d68
  81. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, //e69
  82. 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //f70
  83. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, //g71
  84. 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //h72
  85. 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //i73
  86. 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, //j74
  87. 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, //k75
  88. 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //l76
  89. 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, //m77
  90. 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //n78
  91. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //o79
  92. 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, //p80
  93. 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, //q81
  94. 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, //r82
  95. 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, //s83
  96. 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, //t84
  97. 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, //u85
  98. 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, //v86
  99. 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, //w87
  100. 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, //x88
  101. 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, //y89
  102. 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, //z90
  103. 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{91
  104. 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //|92
  105. 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //}93
  106. 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~94
  107. };
  108. //汉字字模数据 字库字符数组
  109. //温
  110. uint8_t HZ1[]={
  111. 0x10, 0x60, 0x02, 0x8C, 0x00, 0x00, 0xFE, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00,
  112. 0x04, 0x04, 0x7E, 0x01, 0x40, 0x7E, 0x42, 0x42, 0x7E, 0x42, 0x7E, 0x42, 0x42, 0x7E, 0x40, 0x00,
  113. };
  114. //度
  115. uint8_t HZ2[]={
  116. 0x00, 0x00, 0xFC, 0x24, 0x24, 0x24, 0xFC, 0x25, 0x26, 0x24, 0xFC, 0x24, 0x24, 0x24, 0x04, 0x00,
  117. 0x40, 0x30, 0x8F, 0x80, 0x84, 0x4C, 0x55, 0x25, 0x25, 0x25, 0x55, 0x4C, 0x80, 0x80, 0x80, 0x00,
  118. };
  119. //湿
  120. uint8_t HZ3[]={
  121. 0x10, 0x60, 0x02, 0x8C, 0x00, 0xFE, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00,
  122. 0x04, 0x04, 0x7E, 0x01, 0x44, 0x48, 0x50, 0x7F, 0x40, 0x40, 0x7F, 0x50, 0x48, 0x44, 0x40, 0x00,
  123. };
  124. uint8_t jj[] ={
  125. 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00,
  126. 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00,
  127. };
  128. //;"欢",
  129. uint8_t HZ4[] = {
  130. 0X04, 0X24, 0X44, 0X84, 0X64, 0X9C, 0X40, 0X30, 0X0F, 0XC8, 0X08, 0X08, 0X28, 0X18, 0X00, 0X00,
  131. 0X10, 0X08, 0X06, 0X01, 0X82, 0X4C, 0X20, 0X18, 0X06, 0X01, 0X06, 0X18, 0X20, 0X40, 0X80, 0X00,
  132. };
  133. //;"迎",
  134. uint8_t HZ5[] = {
  135. 0X40, 0X40, 0X42, 0XCC, 0X00, 0X00, 0XFC, 0X04, 0X02, 0X00, 0XFC, 0X04, 0X04, 0XFC, 0X00, 0X00,
  136. 0X00, 0X40, 0X20, 0X1F, 0X20, 0X40, 0X4F, 0X44, 0X42, 0X40, 0X7F, 0X42, 0X44, 0X43, 0X40, 0X00,
  137. };
  138. //;"来",
  139. uint8_t HZ6[] = {
  140. 0X00, 0X08, 0X08, 0X28, 0XC8, 0X08, 0X08, 0XFF, 0X08, 0X08, 0X88, 0X68, 0X08, 0X08, 0X00, 0X00,
  141. 0X21, 0X21, 0X11, 0X11, 0X09, 0X05, 0X03, 0XFF, 0X03, 0X05, 0X09, 0X11, 0X11, 0X21, 0X21, 0X00,
  142. };
  143. //;"到",
  144. uint8_t HZ7[] = {
  145. 0X42, 0X62, 0X52, 0X4A, 0XC6, 0X42, 0X52, 0X62, 0XC2, 0X00, 0XF8, 0X00, 0X00, 0XFF, 0X00, 0X00,
  146. 0X40, 0XC4, 0X44, 0X44, 0X7F, 0X24, 0X24, 0X24, 0X20, 0X00, 0X0F, 0X40, 0X80, 0X7F, 0X00, 0X00,
  147. };
  148. //;"智",
  149. uint8_t HZ8[] = {
  150. 0X10, 0X94, 0X53, 0X32, 0X1E, 0X32, 0X52, 0X10, 0X00, 0X7E, 0X42, 0X42, 0X42, 0X7E, 0X00, 0X00,
  151. 0X00, 0X00, 0X00, 0XFF, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0XFF, 0X00, 0X00, 0X00, 0X00,
  152. };
  153. //;"慧",
  154. uint8_t HZ9[] = {
  155. 0X22, 0X2A, 0XAA, 0XFF, 0XAA, 0XAA, 0XA2, 0X80, 0XA2, 0XAA, 0XAA, 0XFF, 0XAA, 0X2A, 0X22, 0X00,
  156. 0X80, 0X60, 0X08, 0X0A, 0X6A, 0X8A, 0X8A, 0X9A, 0XAA, 0X8A, 0X8A, 0XCA, 0X0F, 0X20, 0XC0, 0X00,
  157. };
  158. //;"农",
  159. uint8_t HZ10[] = {
  160. 0X20, 0X18, 0X08, 0X08, 0X08, 0XC8, 0X38, 0XCF, 0X08, 0X08, 0X08, 0X08, 0XA8, 0X18, 0X00, 0X00,
  161. 0X10, 0X08, 0X04, 0X02, 0XFF, 0X40, 0X20, 0X00, 0X03, 0X04, 0X0A, 0X11, 0X20, 0X40, 0X40, 0X00,
  162. };
  163. //;"业",
  164. uint8_t HZ11[] = {
  165. 0X00, 0X10, 0X60, 0X80, 0X00, 0XFF, 0X00, 0X00, 0X00, 0XFF, 0X00, 0X00, 0XC0, 0X30, 0X00, 0X00,
  166. 0X40, 0X40, 0X40, 0X43, 0X40, 0X7F, 0X40, 0X40, 0X40, 0X7F, 0X42, 0X41, 0X40, 0X40, 0X40, 0X00,
  167. };
  168. /*
  169. 0X04,0X24,0X44,0X84,0X64,0X9C,0X40,0X30,0X0F,0XC8,0X08,0X08,0X28,0X18,0X00,0X00,0X10,0X08,0X06,0X01,0X82,0X4C,0X20,0X18,0X06,0X01,0X06,0X18,0X20,0X40,0X80,0X00;"欢",0
  170. 0X40,0X40,0X42,0XCC,0X00,0X00,0XFC,0X04,0X02,0X00,0XFC,0X04,0X04,0XFC,0X00,0X00,0X00,0X40,0X20,0X1F,0X20,0X40,0X4F,0X44,0X42,0X40,0X7F,0X42,0X44,0X43,0X40,0X00;"迎",1
  171. 0X00,0X08,0X08,0X28,0XC8,0X08,0X08,0XFF,0X08,0X08,0X88,0X68,0X08,0X08,0X00,0X00,0X21,0X21,0X11,0X11,0X09,0X05,0X03,0XFF,0X03,0X05,0X09,0X11,0X11,0X21,0X21,0X00;"来",2
  172. 0X42,0X62,0X52,0X4A,0XC6,0X42,0X52,0X62,0XC2,0X00,0XF8,0X00,0X00,0XFF,0X00,0X00,0X40,0XC4,0X44,0X44,0X7F,0X24,0X24,0X24,0X20,0X00,0X0F,0X40,0X80,0X7F,0X00,0X00;"到",3
  173. 0X10,0X94,0X53,0X32,0X1E,0X32,0X52,0X10,0X00,0X7E,0X42,0X42,0X42,0X7E,0X00,0X00,0X00,0X00,0X00,0XFF,0X49,0X49,0X49,0X49,0X49,0X49,0X49,0XFF,0X00,0X00,0X00,0X00;"智",4
  174. 0X22,0X2A,0XAA,0XFF,0XAA,0XAA,0XA2,0X80,0XA2,0XAA,0XAA,0XFF,0XAA,0X2A,0X22,0X00,0X80,0X60,0X08,0X0A,0X6A,0X8A,0X8A,0X9A,0XAA,0X8A,0X8A,0XCA,0X0F,0X20,0XC0,0X00;"慧",5
  175. 0X20,0X18,0X08,0X08,0X08,0XC8,0X38,0XCF,0X08,0X08,0X08,0X08,0XA8,0X18,0X00,0X00,0X10,0X08,0X04,0X02,0XFF,0X40,0X20,0X00,0X03,0X04,0X0A,0X11,0X20,0X40,0X40,0X00;"农",6
  176. 0X00,0X10,0X60,0X80,0X00,0XFF,0X00,0X00,0X00,0XFF,0X00,0X00,0XC0,0X30,0X00,0X00,0X40,0X40,0X40,0X43,0X40,0X7F,0X40,0X40,0X40,0X7F,0X42,0X41,0X40,0X40,0X40,0X00;"业",7
  177. */
  178. //显示温度 和湿度函数
  179. void OLed_ShowTemp(void)
  180. {
  181. //第1行显示温度
  182. OLed_ShowChina( 16, 0,HZ1);
  183. OLed_ShowChina( 32, 0,HZ2);
  184. OLed_ShowASCII( 48, 0, "111"); //显示英文。
  185. //第2行显示湿度
  186. OLed_ShowChina( 16, 2,HZ3);
  187. OLed_ShowChina( 32, 2,HZ2);
  188. }
  189. /*
  190. 写OLED命令寄存器的函数
  191. */
  192. void WriteOLedCmd(uint8_t cmd)
  193. {
  194. uint8_t CtrWord = 0x00;
  195. IIC_Start();
  196. IIC_Send_Byte(OLED_SLAVE_ADDR_WR); //发送从设备地址
  197. IIC_Wait_Ack();
  198. IIC_Send_Byte(CtrWord); //发送命令控制字
  199. IIC_Wait_Ack();
  200. IIC_Send_Byte(cmd);
  201. IIC_Wait_Ack();
  202. IIC_Stop();
  203. }
  204. /*
  205. 写OLED数据的函数
  206. */
  207. void WriteOLedData(uint8_t data)
  208. {
  209. uint8_t CtrWord = 0x00;
  210. CtrWord |= ( 0x1<< 6); //表示发送的是数据
  211. IIC_Start();
  212. IIC_Send_Byte(OLED_SLAVE_ADDR_WR); //发送从设备地址
  213. IIC_Wait_Ack();
  214. IIC_Send_Byte(CtrWord); //发送命令控制字
  215. IIC_Wait_Ack();
  216. IIC_Send_Byte(data);
  217. IIC_Wait_Ack();
  218. IIC_Stop();
  219. }
  220. /*
  221. 设置显示位置
  222. y--> page address页地址 ,相当于 行 (0 ~ 7) 1 100
  223. x --> 列地址 (0 ~ 127)
  224. */
  225. void OLed_SetPos(unsigned char x, unsigned char y)
  226. {
  227. WriteOLedCmd(( 0xb0+y)); //设置行地址,设置页号
  228. WriteOLedCmd(((x& 0xf0)>> 4)| 0x10); //设置列地址高位
  229. WriteOLedCmd((x& 0x0f)| 0x00); //设置列地址的低位
  230. }
  231. #define X_WIDTH 128
  232. /*
  233. 填充显示数据缓冲区
  234. */
  235. void OLed_Fill(unsigned char bmp_data)
  236. {
  237. unsigned char y,x;
  238. for(y= 0;y< 8;y++)
  239. {
  240. //设置PAGE地址
  241. WriteOLedCmd( 0xb0+y);
  242. //设置列地址
  243. WriteOLedCmd( 0x00);
  244. WriteOLedCmd( 0x10);
  245. for(x= 0;x<X_WIDTH;x++)
  246. {
  247. WriteOLedData(bmp_data);
  248. }
  249. }
  250. }
  251. //-----------------------------------------------------//
  252. //1 打开oled函数
  253. void InitOLed(void)
  254. {
  255. //给OLED发送命令 初始化OLED
  256. WriteOLedCmd( 0xAE); //--turn off oled panel
  257. WriteOLedCmd( 0x00); //---set low column address
  258. WriteOLedCmd( 0x10); //---set high column address
  259. WriteOLedCmd( 0x40); //--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
  260. WriteOLedCmd( 0x81); //--set contrast control register
  261. WriteOLedCmd( 0xCF); // Set SEG Output Current Brightness
  262. WriteOLedCmd( 0xA1); //--Set SEG/Column Mapping 0xa0???? 0xa1??
  263. WriteOLedCmd( 0xC8); //Set COM/Row Scan Direction 0xc0???? 0xc8??
  264. WriteOLedCmd( 0xA6); //--set normal display
  265. WriteOLedCmd( 0xA8); //--set multiplex ratio(1 to 64)
  266. WriteOLedCmd( 0x3f); //--1/64 duty
  267. WriteOLedCmd( 0xD3); //-set display offset Shift Mapping RAM Counter (0x00~0x3F)
  268. WriteOLedCmd( 0x00); //-not offset
  269. WriteOLedCmd( 0xd5); //--set display clock divide ratio/oscillator frequency
  270. WriteOLedCmd( 0x80); //--set divide ratio, Set Clock as 100 Frames/Sec
  271. WriteOLedCmd( 0xD9); //--set pre-charge period
  272. WriteOLedCmd( 0xF1); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  273. WriteOLedCmd( 0xDA); //--set com pins hardware configuration
  274. WriteOLedCmd( 0x12);
  275. WriteOLedCmd( 0xDB); //--set vcomh
  276. WriteOLedCmd( 0x40); //Set VCOM Deselect Level
  277. WriteOLedCmd( 0x20); //-Set Page Addressing Mode (0x00/0x01/0x02)
  278. WriteOLedCmd( 0x02); //
  279. WriteOLedCmd( 0x8D); //--set Charge Pump enable/disable
  280. WriteOLedCmd( 0x14); //--set(0x10) disable
  281. WriteOLedCmd( 0xA4); // Disable Entire Display On (0xa4/0xa5)
  282. WriteOLedCmd( 0xA6); // Disable Inverse Display On (0xa6/a7)
  283. WriteOLedCmd( 0xAF); //--turn on oled panel
  284. WriteOLedCmd( 0xAF); /*display ON*/
  285. OLed_Fill( 0x00);
  286. }
  287. //2oled关闭函数
  288. void offInitOLed(void)
  289. {
  290. //给OLED发送命令 初始化OLED
  291. WriteOLedCmd( 0xAE); //--turn off oled panel
  292. WriteOLedCmd( 0x00); //---set low column address
  293. WriteOLedCmd( 0x10); //---set high column address
  294. WriteOLedCmd( 0x40); //--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
  295. WriteOLedCmd( 0x81); //--set contrast control register
  296. WriteOLedCmd( 0xCF); // Set SEG Output Current Brightness
  297. WriteOLedCmd( 0xA1); //--Set SEG/Column Mapping 0xa0???? 0xa1??
  298. WriteOLedCmd( 0xC8); //Set COM/Row Scan Direction 0xc0???? 0xc8??
  299. WriteOLedCmd( 0xA6); //--set normal display
  300. WriteOLedCmd( 0xA8); //--set multiplex ratio(1 to 64)
  301. WriteOLedCmd( 0x3f); //--1/64 duty
  302. WriteOLedCmd( 0xD3); //-set display offset Shift Mapping RAM Counter (0x00~0x3F)
  303. WriteOLedCmd( 0x00); //-not offset
  304. WriteOLedCmd( 0xd5); //--set display clock divide ratio/oscillator frequency
  305. WriteOLedCmd( 0x80); //--set divide ratio, Set Clock as 100 Frames/Sec
  306. WriteOLedCmd( 0xD9); //--set pre-charge period
  307. WriteOLedCmd( 0xF1); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  308. WriteOLedCmd( 0xDA); //--set com pins hardware configuration
  309. WriteOLedCmd( 0x12);
  310. WriteOLedCmd( 0xDB); //--set vcomh
  311. WriteOLedCmd( 0x40); //Set VCOM Deselect Level
  312. WriteOLedCmd( 0x20); //-Set Page Addressing Mode (0x00/0x01/0x02)
  313. WriteOLedCmd( 0x02); //
  314. WriteOLedCmd( 0x8D); //--set Charge Pump enable/disable
  315. WriteOLedCmd( 0x14); //--set(0x10) disable
  316. WriteOLedCmd( 0xA4); // Disable Entire Display On (0xa4/0xa5)
  317. WriteOLedCmd( 0xA6); // Disable Inverse Display On (0xa6/a7)
  318. WriteOLedCmd( 0xAF); //--turn on oled panel
  319. }
  320. /***********************************显示3个函数*************************************************/
  321. uint8_t fbuf1[]={ 0x00, 0x00, 0xF0, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00};
  322. uint8_t fbuf2[]={ 0x00, 0x00, 0x0F, 0x04, 0x04, 0x04, 0x04, 0xFF, 0x04, 0x04, 0x04, 0x04, 0x0F, 0x00, 0x00, 0x00}; /*中*/
  323. uint8_t fbuf3[]={ 0x00, 0xFE, 0x02, 0x12, 0x92, 0x92, 0x92, 0xF2, 0x92, 0x92, 0x92, 0x12, 0x02, 0xFE, 0x00, 0x00};
  324. uint8_t fbuf4[]={ 0x00, 0xFF, 0x40, 0x48, 0x48, 0x48, 0x48, 0x4F, 0x48, 0x4A, 0x4C, 0x48, 0x40, 0xFF, 0x00, 0x00}; /*国*/
  325. /*
  326. 功能:在指定位置显示指定ASCII码对应字符串
  327. @x: 显示的行号(页号0~7)
  328. @y:显示的列号(列号0~127)
  329. @str: 要显示的ascii的字符串
  330. */
  331. //3.显示字母函数
  332. void OLed_ShowASCII(uint8_t x, uint8_t y,char *str)
  333. {
  334. uint8_t i = 0;
  335. char *pstr = str;
  336. while(*pstr)
  337. {
  338. OLed_SetPos(x,y);
  339. for(i= 0;i< 8;i++)
  340. {
  341. WriteOLedData(F8X16[((*pstr) -32)* 16+i]);
  342. }
  343. OLed_SetPos(x,y+ 1);
  344. for(i= 0;i< 8;i++)
  345. {
  346. WriteOLedData(F8X16[((*pstr) -32)* 16+ 8+i]);
  347. }
  348. pstr++;
  349. x += 8;
  350. }
  351. }
  352. /*
  353. 功能: 在指定位置显示一个汉字, 显示下一个汉字时,X每次递增16
  354. Y递增 2 字模数据 buf
  355. */
  356. //4.显示汉字函数
  357. void OLed_ShowChina(uint8_t x,uint8_t y,uint8_t *buf)
  358. {
  359. uint8_t i = 0;
  360. OLed_SetPos(x,y);
  361. for(i= 0;i< 16;i++)
  362. {
  363. WriteOLedData(buf[i]);
  364. }
  365. OLed_SetPos(x,(y+ 1));
  366. for(i= 0;i< 16;i++)
  367. {
  368. WriteOLedData(buf[i+ 16]);
  369. }
  370. }
  371. /*
  372. 在 x,y 位置显示
  373. */
  374. void OLed_ShowTest(unsigned char x,unsigned char y)
  375. {
  376. uint8_t i = 0;
  377. OLed_SetPos(x,y);
  378. for(i= 0;i< 16;i++)
  379. {
  380. WriteOLedData(fbuf1[i]);
  381. }
  382. OLed_SetPos(x,(y+ 1));
  383. for(i= 0;i< 16;i++)
  384. {
  385. WriteOLedData(fbuf2[i]);
  386. }
  387. OLed_SetPos((x+ 16),y);
  388. for(i= 0;i< 16;i++)
  389. {
  390. WriteOLedData(fbuf3[i]);
  391. }
  392. OLed_SetPos((x+ 16),(y+ 1));
  393. for(i= 0;i< 16;i++)
  394. {
  395. WriteOLedData(fbuf4[i]);
  396. }
  397. }

17.myusart.h


  
  1. #ifndef __MY_USART_H__
  2. #define __MY_USART_H__
  3. #include "stm32f4xx_rcc.h"
  4. #define USART_REC_LEN 50
  5. extern u8 USART_RX_BUF[USART_REC_LEN]; //数据接收的数组
  6. extern u16 USART_RX_STA; //接受完成的标志 ,如果最高位是1 则接受完成
  7. void myusart_init(int usart_btl); //初始化
  8. void printt(char str[],unsigned char num); //输出函数 串口传输函数
  9. #endif

18.myusart.c


  
  1. #include "myusart.h"
  2. #include "stm32f4xx_usart.h"
  3. #include "stm32f4xx_gpio.h"
  4. #include "stdio.h"
  5. #include "string.h"
  6. #include "delay.h"
  7. u8 USART_RX_BUF[USART_REC_LEN];
  8. u16 USART_RX_STA = 0; //接受完成的标志
  9. char wendu[ 30] = "";
  10. char str[ 128] = "\0";
  11. char i = 0 ;
  12. #pragma import(__use_no_semihosting)
  13. //标准库需要的支持函数
  14. struct __FILE
  15. {
  16. int handle;
  17. };
  18. FILE __stdout;
  19. //定义_sys_exit()以避免使用半主机模式
  20. void _sys_exit( int x)
  21. {
  22. x=x;
  23. }
  24. int fputc(int ch,FILE *f)
  25. {
  26. #if 0
  27. while( (USART1->SR&( 1<< 6))== 0 ); //发送未完成等待
  28. USART1->DR = ( unsigned char)ch; //发送完成,那么可以向DR写入下一个待发送的数据
  29. return ch;
  30. #else
  31. while( USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
  32. USART_SendData(USART1,( unsigned char)ch);
  33. return ch;
  34. #endif
  35. }
  36. int fgetc(FILE *f)
  37. {
  38. #if 0
  39. while((USART1->SR&( 1<< 5)) == 0); //数据寄存器非空(即:接收到数据),那么跳出循环,否则一直等待
  40. return(( int)(USART1->DR& 0xff)); //接收完成,读取数据。
  41. #else
  42. while( USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);
  43. return(( int)( USART_ReceiveData(USART1)));
  44. #endif
  45. }
  46. void myusart_init(int usart_btl)
  47. {
  48. //第一步:准备三个结构体
  49. USART_InitTypeDef USART_InitStruct; // 串口通信
  50. NVIC_InitTypeDef NVIC_InitStruct ; // 中断寄存器NVIC
  51. GPIO_InitTypeDef GPIO_InitStruct; //GPIO设置结构体
  52. //第二步: 时钟使能
  53. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //串口时钟使能
  54. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //GPIO口时钟使能
  55. //第三步: 设置端口复用
  56. GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_USART1);
  57. //把A组中的10引脚设置成串口1模式(复用)
  58. GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_USART1);
  59. //
  60. //第四步: 设置GPIO口的模式 (PA9 --TXD PA10 ---RXD)
  61. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF ; //复用功能
  62. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  63. GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  64. GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  65. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  66. GPIO_Init( GPIOA ,&GPIO_InitStruct);
  67. GPIO_SetBits(GPIOA,GPIO_Pin_9);
  68. /*GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
  69. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
  70. GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  71. GPIO_Init( GPIOA ,&GPIO_InitStruct);*/
  72. // 第五步: 设置usart寄存器
  73. USART_InitStruct.USART_BaudRate = usart_btl; // 波特率
  74. USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 硬件流
  75. USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //允许接受和发送
  76. USART_InitStruct.USART_Parity = USART_Parity_No; // 奇偶校验位(无)
  77. USART_InitStruct.USART_StopBits = USART_StopBits_1; //停止位 (1位)
  78. USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 字长 (8位)
  79. USART_Init(USART1,&USART_InitStruct);
  80. //第六步: 设置中断寄存器
  81. NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; // 中断号
  82. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //终端号使能
  83. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
  84. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; // 响应优先级
  85. NVIC_Init(&NVIC_InitStruct);
  86. //第七步: 设置接收中断使能 设置串口使能
  87. USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //接收数据中断
  88. USART_Cmd(USART1,ENABLE);
  89. }
  90. //发送数据 aabcdef\r\n
  91. //串口1中断服务程序
  92. u8 count = 0;
  93. void USART1_IRQHandler(void)
  94. {
  95. u8 Res;
  96. //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  97. if( USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  98. {
  99. Res = USART_ReceiveData(USART1); //(USART1->DR); //读取接收到的数据
  100. //printf("111");
  101. if((USART_RX_STA& 0x8000)== 0) //接收未完成
  102. {
  103. if(USART_RX_STA& 0x4000) //接收到了0x0d 0100 0000 0000 0000
  104. {
  105. if(Res!= '\n')USART_RX_STA= 0; //接收错误,重新开始
  106. else USART_RX_STA|= 0x8000; //接收完成了
  107. }
  108. else //还没收到‘\r’
  109. {
  110. if(Res== '\r')USART_RX_STA|= 0x4000; //USART_RX_STA = 1100 0000 0000 0000
  111. else //USART_RX_BUF[0] = 'd'; USART_RX_BUF[1] = 'a';.. USART_RX_BUF[4] = 'y'
  112. {
  113. USART_RX_BUF[USART_RX_STA& 0X3FFF]=Res ; // danny\r\n
  114. USART_RX_STA++;
  115. //接收数据错误,重新开始接收
  116. if(USART_RX_STA>(USART_REC_LEN -1))USART_RX_STA= 0;
  117. }
  118. }
  119. }
  120. }
  121. }
  122. void printt(char str[],unsigned char num)
  123. {
  124. unsigned char i = 0 ;
  125. for(i = 0 ; i < strlen(str);i++)
  126. {
  127. USART_SendData(USART1,str[i]);
  128. delay_ms( 5);
  129. }
  130. //格式化函数,把十六进制转换成字符串
  131. sprintf(wendu, "%d",num);
  132. //添加一个换行符
  133. strcat(wendu, "\r\n");
  134. //串口打印函数
  135. for(i = 0 ; i < strlen(wendu);i++)
  136. {
  137. USART_SendData(USART1,wendu[i]);
  138. delay_ms( 5);
  139. }
  140. }
  141. //进行串口通信,当用户发送01+02 串口接受到后 发送03 给到pc
  142. /*
  143. SysTick_init(168);
  144. //中断分组
  145. u16 len = 0;
  146. int i = 0;
  147. SysTick_init(168);//初始化延时函数
  148. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  149. myusart_init(115200);
  150. while(1)
  151. {
  152. //数据接收完成
  153. if(USART_RX_STA&0x8000)
  154. {
  155. len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
  156. for(i=0;i<len;i++)
  157. {
  158. USART_SendData(USART1, USART_RX_BUF[i]);
  159. //等待发送结束
  160. while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
  161. }
  162. if(len == 5)
  163. {
  164. if(USART_RX_BUF[2]==43)
  165. {
  166. int a1=((int)(USART_RX_BUF[0] -48)*10 )+ (int)(USART_RX_BUF[1] -48);
  167. int a2=((int)(USART_RX_BUF[3] -48)*10 )+ (int)(USART_RX_BUF[4] -48);
  168. int a3= a1+a2;
  169. if(a3<10)
  170. {
  171. printf("= 0%d \r\n",a3);
  172. }
  173. else
  174. {
  175. printf("= %d \r\n",a3);
  176. }
  177. }
  178. else if(USART_RX_BUF[2]==45)
  179. {
  180. int a1=((int)(USART_RX_BUF[0] -48)*10 )+ (int)(USART_RX_BUF[1] -48);
  181. int a2=((int)(USART_RX_BUF[3] -48)*10 )+ (int)(USART_RX_BUF[4] -48);
  182. int a3= a1-a2;
  183. if(a3<10)
  184. {
  185. printf("= %d \r\n",a3);
  186. }
  187. else
  188. {
  189. printf("= %d \r\n",a3);
  190. }
  191. }
  192. }
  193. USART_RX_STA=0;
  194. }
  195. }
  196. */

19. PWM.h 


  
  1. #include "myusart.h"
  2. #include "stm32f4xx_usart.h"
  3. #include "stm32f4xx_gpio.h"
  4. #include "stdio.h"
  5. #include "string.h"
  6. #include "delay.h"
  7. u8 USART_RX_BUF[USART_REC_LEN];
  8. u16 USART_RX_STA = 0; //接受完成的标志
  9. char wendu[ 30] = "";
  10. char str[ 128] = "\0";
  11. char i = 0 ;
  12. #pragma import(__use_no_semihosting)
  13. //标准库需要的支持函数
  14. struct __FILE
  15. {
  16. int handle;
  17. };
  18. FILE __stdout;
  19. //定义_sys_exit()以避免使用半主机模式
  20. void _sys_exit( int x)
  21. {
  22. x=x;
  23. }
  24. int fputc(int ch,FILE *f)
  25. {
  26. #if 0
  27. while( (USART1->SR&( 1<< 6))== 0 ); //发送未完成等待
  28. USART1->DR = ( unsigned char)ch; //发送完成,那么可以向DR写入下一个待发送的数据
  29. return ch;
  30. #else
  31. while( USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
  32. USART_SendData(USART1,( unsigned char)ch);
  33. return ch;
  34. #endif
  35. }
  36. int fgetc(FILE *f)
  37. {
  38. #if 0
  39. while((USART1->SR&( 1<< 5)) == 0); //数据寄存器非空(即:接收到数据),那么跳出循环,否则一直等待
  40. return(( int)(USART1->DR& 0xff)); //接收完成,读取数据。
  41. #else
  42. while( USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);
  43. return(( int)( USART_ReceiveData(USART1)));
  44. #endif
  45. }
  46. void myusart_init(int usart_btl)
  47. {
  48. //第一步:准备三个结构体
  49. USART_InitTypeDef USART_InitStruct; // 串口通信
  50. NVIC_InitTypeDef NVIC_InitStruct ; // 中断寄存器NVIC
  51. GPIO_InitTypeDef GPIO_InitStruct; //GPIO设置结构体
  52. //第二步: 时钟使能
  53. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //串口时钟使能
  54. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //GPIO口时钟使能
  55. //第三步: 设置端口复用
  56. GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_USART1);
  57. //把A组中的10引脚设置成串口1模式(复用)
  58. GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_USART1);
  59. //
  60. //第四步: 设置GPIO口的模式 (PA9 --TXD PA10 ---RXD)
  61. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF ; //复用功能
  62. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  63. GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  64. GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  65. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  66. GPIO_Init( GPIOA ,&GPIO_InitStruct);
  67. GPIO_SetBits(GPIOA,GPIO_Pin_9);
  68. /*GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
  69. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
  70. GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  71. GPIO_Init( GPIOA ,&GPIO_InitStruct);*/
  72. // 第五步: 设置usart寄存器
  73. USART_InitStruct.USART_BaudRate = usart_btl; // 波特率
  74. USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 硬件流
  75. USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //允许接受和发送
  76. USART_InitStruct.USART_Parity = USART_Parity_No; // 奇偶校验位(无)
  77. USART_InitStruct.USART_StopBits = USART_StopBits_1; //停止位 (1位)
  78. USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 字长 (8位)
  79. USART_Init(USART1,&USART_InitStruct);
  80. //第六步: 设置中断寄存器
  81. NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; // 中断号
  82. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //终端号使能
  83. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
  84. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; // 响应优先级
  85. NVIC_Init(&NVIC_InitStruct);
  86. //第七步: 设置接收中断使能 设置串口使能
  87. USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //接收数据中断
  88. USART_Cmd(USART1,ENABLE);
  89. }
  90. //发送数据 aabcdef\r\n
  91. //串口1中断服务程序
  92. u8 count = 0;
  93. void USART1_IRQHandler(void)
  94. {
  95. u8 Res;
  96. //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  97. if( USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  98. {
  99. Res = USART_ReceiveData(USART1); //(USART1->DR); //读取接收到的数据
  100. //printf("111");
  101. if((USART_RX_STA& 0x8000)== 0) //接收未完成
  102. {
  103. if(USART_RX_STA& 0x4000) //接收到了0x0d 0100 0000 0000 0000
  104. {
  105. if(Res!= '\n')USART_RX_STA= 0; //接收错误,重新开始
  106. else USART_RX_STA|= 0x8000; //接收完成了
  107. }
  108. else //还没收到‘\r’
  109. {
  110. if(Res== '\r')USART_RX_STA|= 0x4000; //USART_RX_STA = 1100 0000 0000 0000
  111. else //USART_RX_BUF[0] = 'd'; USART_RX_BUF[1] = 'a';.. USART_RX_BUF[4] = 'y'
  112. {
  113. USART_RX_BUF[USART_RX_STA& 0X3FFF]=Res ; // danny\r\n
  114. USART_RX_STA++;
  115. //接收数据错误,重新开始接收
  116. if(USART_RX_STA>(USART_REC_LEN -1))USART_RX_STA= 0;
  117. }
  118. }
  119. }
  120. }
  121. }
  122. void printt(char str[],unsigned char num)
  123. {
  124. unsigned char i = 0 ;
  125. for(i = 0 ; i < strlen(str);i++)
  126. {
  127. USART_SendData(USART1,str[i]);
  128. delay_ms( 5);
  129. }
  130. //格式化函数,把十六进制转换成字符串
  131. sprintf(wendu, "%d",num);
  132. //添加一个换行符
  133. strcat(wendu, "\r\n");
  134. //串口打印函数
  135. for(i = 0 ; i < strlen(wendu);i++)
  136. {
  137. USART_SendData(USART1,wendu[i]);
  138. delay_ms( 5);
  139. }
  140. }
  141. //进行串口通信,当用户发送01+02 串口接受到后 发送03 给到pc
  142. /*
  143. SysTick_init(168);
  144. //中断分组
  145. u16 len = 0;
  146. int i = 0;
  147. SysTick_init(168);//初始化延时函数
  148. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  149. myusart_init(115200);
  150. while(1)
  151. {
  152. //数据接收完成
  153. if(USART_RX_STA&0x8000)
  154. {
  155. len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
  156. for(i=0;i<len;i++)
  157. {
  158. USART_SendData(USART1, USART_RX_BUF[i]);
  159. //等待发送结束
  160. while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
  161. }
  162. if(len == 5)
  163. {
  164. if(USART_RX_BUF[2]==43)
  165. {
  166. int a1=((int)(USART_RX_BUF[0] -48)*10 )+ (int)(USART_RX_BUF[1] -48);
  167. int a2=((int)(USART_RX_BUF[3] -48)*10 )+ (int)(USART_RX_BUF[4] -48);
  168. int a3= a1+a2;
  169. if(a3<10)
  170. {
  171. printf("= 0%d \r\n",a3);
  172. }
  173. else
  174. {
  175. printf("= %d \r\n",a3);
  176. }
  177. }
  178. else if(USART_RX_BUF[2]==45)
  179. {
  180. int a1=((int)(USART_RX_BUF[0] -48)*10 )+ (int)(USART_RX_BUF[1] -48);
  181. int a2=((int)(USART_RX_BUF[3] -48)*10 )+ (int)(USART_RX_BUF[4] -48);
  182. int a3= a1-a2;
  183. if(a3<10)
  184. {
  185. printf("= %d \r\n",a3);
  186. }
  187. else
  188. {
  189. printf("= %d \r\n",a3);
  190. }
  191. }
  192. }
  193. USART_RX_STA=0;
  194. }
  195. }
  196. */

20. PWM.c


  
  1. #include "pwm.h"
  2. #include "stm32f4xx.h"
  3. #include "delay.h"
  4. //TIM14 PWM部分初始化
  5. //PWM输出初始化
  6. //arr:自动重装值
  7. //psc:时钟预分频数
  8. void TIM14_PWM_Init(void)
  9. {
  10. //此部分需手动修改IO口设置
  11. GPIO_InitTypeDef GPIO_InitStructure;
  12. //定时器结构体初始化。
  13. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  14. TIM_OCInitTypeDef TIM_OCInitStructure;
  15. //1TIM14时钟使能
  16. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
  17. 2使能PORTF时钟
  18. TIM_DeInit(TIM1);
  19. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
  20. //3GPIOF9复用为定时器14 // Device header
  21. GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_TIM1);
  22. //GPIOF9
  23. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  24. //复用功能
  25. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  26. //速度100MHz
  27. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  28. //推挽复用输出
  29. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  30. //上拉
  31. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  32. //4初始化PF9
  33. GPIO_Init(GPIOE,&GPIO_InitStructure);
  34. TIM_TimeBaseStructure.TIM_Prescaler= 400; //定时器分频
  35. TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
  36. TIM_TimeBaseStructure.TIM_Period= 100; //自动重装载值
  37. TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  38. // TIM_TimeBaseStructure.TIM_RepetitionCounter = 1;
  39. //5初始化定时器14
  40. TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
  41. //初始化TIM14 Channel1 PWM模式
  42. //选择定时器模式:TIM脉冲宽度调制模式2
  43. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  44. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  45. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  46. TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  47. //6根据T指定的参数初始化外设TIM1 4OC1
  48. // TIM_OCInitStructure.TIM_Pulse = 100;
  49. TIM_OC1Init(TIM1, &TIM_OCInitStructure);
  50. //7使能TIM14在CCR1上的预装载寄存器
  51. // TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
  52. // //8ARPE使能
  53. // TIM_ARRPreloadConfig(TIM1,ENABLE);
  54. //9使能TIM14
  55. TIM_Cmd(TIM1, ENABLE);
  56. TIM_CtrlPWMOutputs(TIM1, ENABLE);
  57. }
  58. void ppp(int a)// 呼吸灯
  59. {
  60. static u16 led0pwmval= 0;
  61. if(a< 0)
  62. {
  63. led0pwmval= 0;
  64. }
  65. else if(a>= 100)
  66. {
  67. led0pwmval= 100;
  68. }
  69. else
  70. {
  71. led0pwmval =a;
  72. }
  73. //修改比较值,修改占空比
  74. TIM_SetCompare1(TIM1,led0pwmval);
  75. }


21.wwdg.h


  
  1. #ifndef __WWDG_H__
  2. #define __WWDG_H__
  3. void wwdginit(void); //窗口看门狗初始化
  4. #endif

22.wwdg.c


  
  1. #include "stm32f4xx.h"
  2. #include "wwdg.h"
  3. #include "delay.h"
  4. #include "misc.h"
  5. //当前值寄存器从自定义 0x7f 递减
  6. //0x5f:自定的窗口上限值
  7. //0x3f:固定的串口下限值
  8. //只有窗口期才可以喂狗,如果喂狗,系统就不会重启,否则,如果没有配置中断功能,程序就会重启。
  9. //如果窗口期没有喂狗,自动进入到中断函数中。可以在中断函数中进行喂狗。
  10. //窗口看门狗可以配置中断。
  11. void wwdginit()
  12. {
  13. //1.配置时钟
  14. RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
  15. //2设置分频值:WWDG_Prescaler_8
  16. WWDG_SetPrescaler(WWDG_Prescaler_8);
  17. //3设置窗口值 : 窗口上限值。只要比 0x3f大就行。
  18. WWDG_SetWindowValue( 0x6F);
  19. //4.开启看门狗
  20. WWDG_Enable( 0x7F);
  21. //5.配置窗口看门狗中断类型
  22. NVIC_InitTypeDef wwdgstruct;
  23. wwdgstruct.NVIC_IRQChannel= WWDG_IRQn;
  24. //抢占优先级为2
  25. wwdgstruct.NVIC_IRQChannelPreemptionPriority= 0x00;
  26. wwdgstruct.NVIC_IRQChannelSubPriority= 0x00;
  27. //子优先级为3
  28. wwdgstruct.NVIC_IRQChannelCmd=ENABLE;
  29. //使能窗口看门狗中断
  30. NVIC_Init(&wwdgstruct);
  31. //6清除提前唤醒中断标志位:防止提前进入中断函数中。
  32. WWDG_ClearFlag();
  33. //7开启中断函数使能.让窗口看门狗可以使用中断功能
  34. WWDG_EnableIT();
  35. }
  36. //窗口看门狗中断函数一定是这个。
  37. //1.有没有进入中断函数中 ok
  38. //2.为什么一直重启? 时间问题。
  39. void WWDG_IRQHandler(void)
  40. {
  41. //重设窗口看门狗值 喂狗 防止重启
  42. WWDG_SetCounter( 0x5f); //0x7f - 0x3f : 0x5f - 0x3f ;
  43. //清除提前唤醒中断标志位
  44. WWDG_ClearFlag();
  45. //喂狗的数值一定要在窗口期内:一定要在5f - 3f之间
  46. }


上位机的系统文件

 23. delay.h


  
  1. #ifndef __DELAY_H
  2. #define __DELAY_H
  3. #include <sys.h>
  4. //
  5. void delay_init(u8 SYSCLK);
  6. void delay_ms(u16 nms);
  7. void delay_us(u32 nus);
  8. #endif

24.delay.c


  
  1. #include "delay.h"
  2. #include "sys.h"
  3. #include "misc.h"
  4. //
  5. //如果使用OS,则包括下面的头文件(以ucos为例)即可.
  6. #if SYSTEM_SUPPORT_OS
  7. #include "includes.h" //支持OS时,使用
  8. #endif
  9. //
  10. //********************************************************************************
  11. //
  12. static u8 fac_us= 0; //us延时倍乘数
  13. static u16 fac_ms= 0; //ms延时倍乘数,在os下,代表每个节拍的ms数
  14. #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS定义了,说明要支持OS了(不限于UCOS).
  15. //当delay_us/delay_ms需要支持OS的时候需要三个与OS相关的宏定义和函数来支持
  16. //首先是3个宏定义:
  17. // delay_osrunning:用于表示OS当前是否正在运行,以决定是否可以使用相关函数
  18. //delay_ostickspersec:用于表示OS设定的时钟节拍,delay_init将根据这个参数来初始哈systick
  19. // delay_osintnesting:用于表示OS中断嵌套级别,因为中断里面不可以调度,delay_ms使用该参数来决定如何运行
  20. //然后是3个函数:
  21. // delay_osschedlock:用于锁定OS任务调度,禁止调度
  22. //delay_osschedunlock:用于解锁OS任务调度,重新开启调度
  23. // delay_ostimedly:用于OS延时,可以引起任务调度.
  24. //本例程仅作UCOSII和UCOSIII的支持,其他OS,请自行参考着移植
  25. //支持UCOSII
  26. #ifdef OS_CRITICAL_METHOD //OS_CRITICAL_METHOD定义了,说明要支持UCOSII
  27. #define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行
  28. #define delay_ostickspersec OS_TICKS_PER_SEC //OS时钟节拍,即每秒调度次数
  29. #define delay_osintnesting OSIntNesting //中断嵌套级别,即中断嵌套次数
  30. #endif
  31. //支持UCOSIII
  32. #ifdef CPU_CFG_CRITICAL_METHOD //CPU_CFG_CRITICAL_METHOD定义了,说明要支持UCOSIII
  33. #define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行
  34. #define delay_ostickspersec OSCfg_TickRate_Hz //OS时钟节拍,即每秒调度次数
  35. #define delay_osintnesting OSIntNestingCtr //中断嵌套级别,即中断嵌套次数
  36. #endif
  37. //us级延时时,关闭任务调度(防止打断us级延迟)
  38. void delay_osschedlock(void)
  39. {
  40. #ifdef CPU_CFG_CRITICAL_METHOD //使用UCOSIII
  41. OS_ERR err;
  42. OSSchedLock(&err); //UCOSIII的方式,禁止调度,防止打断us延时
  43. #else //否则UCOSII
  44. OSSchedLock(); //UCOSII的方式,禁止调度,防止打断us延时
  45. #endif
  46. }
  47. //us级延时时,恢复任务调度
  48. void delay_osschedunlock(void)
  49. {
  50. #ifdef CPU_CFG_CRITICAL_METHOD //使用UCOSIII
  51. OS_ERR err;
  52. OSSchedUnlock(&err); //UCOSIII的方式,恢复调度
  53. #else //否则UCOSII
  54. OSSchedUnlock(); //UCOSII的方式,恢复调度
  55. #endif
  56. }
  57. //调用OS自带的延时函数延时
  58. //ticks:延时的节拍数
  59. void delay_ostimedly(u32 ticks)
  60. {
  61. #ifdef CPU_CFG_CRITICAL_METHOD
  62. OS_ERR err;
  63. OSTimeDly(ticks,OS_OPT_TIME_PERIODIC,&err); //UCOSIII延时采用周期模式
  64. #else
  65. OSTimeDly(ticks); //UCOSII延时
  66. #endif
  67. }
  68. //systick中断服务函数,使用OS时用到
  69. void SysTick_Handler(void)
  70. {
  71. if(delay_osrunning== 1) //OS开始跑了,才执行正常的调度处理
  72. {
  73. OSIntEnter(); //进入中断
  74. OSTimeTick(); //调用ucos的时钟服务程序
  75. OSIntExit(); //触发任务切换软中断
  76. }
  77. }
  78. #endif
  79. //初始化延迟函数
  80. //当使用OS的时候,此函数会初始化OS的时钟节拍
  81. //SYSTICK的时钟固定为AHB时钟的1/8
  82. //SYSCLK:系统时钟频率
  83. void delay_init(u8 SYSCLK)
  84. {
  85. #if SYSTEM_SUPPORT_OS //如果需要支持OS.
  86. u32 reload;
  87. #endif
  88. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  89. fac_us=SYSCLK/ 8; //不论是否使用OS,fac_us都需要使用
  90. #if SYSTEM_SUPPORT_OS //如果需要支持OS.
  91. reload=SYSCLK/ 8; //每秒钟的计数次数 单位为M
  92. reload*= 1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间
  93. //reload为24位寄存器,最大值:16777216,在168M下,约合0.7989s左右
  94. fac_ms= 1000/delay_ostickspersec; //代表OS可以延时的最少单位
  95. SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
  96. SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次
  97. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
  98. #else
  99. fac_ms=(u16)fac_us* 1000; //非OS下,代表每个ms需要的systick时钟数
  100. #endif
  101. }
  102. #if SYSTEM_SUPPORT_OS //如果需要支持OS.
  103. //延时nus
  104. //nus:要延时的us数.
  105. //nus:0~204522252(最大值即2^32/fac_us@fac_us=21)
  106. void delay_us(u32 nus)
  107. {
  108. u32 ticks;
  109. u32 told,tnow,tcnt= 0;
  110. u32 reload=SysTick->LOAD; //LOAD的值
  111. ticks=nus*fac_us; //需要的节拍数
  112. delay_osschedlock(); //阻止OS调度,防止打断us延时
  113. told=SysTick->VAL; //刚进入时的计数器值
  114. while( 1)
  115. {
  116. tnow=SysTick->VAL;
  117. if(tnow!=told)
  118. {
  119. if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.
  120. else tcnt+=reload-tnow+told;
  121. told=tnow;
  122. if(tcnt>=ticks) break; //时间超过/等于要延迟的时间,则退出.
  123. }
  124. };
  125. delay_osschedunlock(); //恢复OS调度
  126. }
  127. //延时nms
  128. //nms:要延时的ms数
  129. //nms:0~65535
  130. void delay_ms(u16 nms)
  131. {
  132. if(delay_osrunning&&delay_osintnesting== 0) //如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度)
  133. {
  134. if(nms>=fac_ms) //延时的时间大于OS的最少时间周期
  135. {
  136. delay_ostimedly(nms/fac_ms); //OS延时
  137. }
  138. nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时
  139. }
  140. delay_us((u32)(nms* 1000)); //普通方式延时
  141. }
  142. #else //不用ucos时
  143. //延时nus
  144. //nus为要延时的us数.
  145. //注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21)
  146. void delay_us(u32 nus)
  147. {
  148. u32 temp;
  149. SysTick->LOAD=nus*fac_us; //时间加载
  150. SysTick->VAL= 0x00; //清空计数器
  151. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
  152. do
  153. {
  154. temp=SysTick->CTRL;
  155. } while((temp& 0x01)&&!(temp&( 1<< 16))); //等待时间到达
  156. SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
  157. SysTick->VAL = 0X00; //清空计数器
  158. }
  159. //延时nms
  160. //注意nms的范围
  161. //SysTick->LOAD为24位寄存器,所以,最大延时为:
  162. //nms<=0xffffff*8*1000/SYSCLK
  163. //SYSCLK单位为Hz,nms单位为ms
  164. //对168M条件下,nms<=798ms
  165. void delay_xms(u16 nms)
  166. {
  167. u32 temp;
  168. SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
  169. SysTick->VAL = 0x00; //清空计数器
  170. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
  171. do
  172. {
  173. temp=SysTick->CTRL;
  174. } while((temp& 0x01)&&!(temp&( 1<< 16))); //等待时间到达
  175. SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
  176. SysTick->VAL = 0X00; //清空计数器
  177. }
  178. //延时nms
  179. //nms:0~65535
  180. void delay_ms(u16 nms)
  181. {
  182. u8 repeat=nms/ 540; //这里用540,是考虑到某些客户可能超频使用,
  183. //比如超频到248M的时候,delay_xms最大只能延时541ms左右了
  184. u16 remain=nms% 540;
  185. while(repeat)
  186. {
  187. delay_xms( 540);
  188. repeat--;
  189. }
  190. if(remain) delay_xms(remain);
  191. }
  192. #endif

25. sys.h


  
  1. #ifndef __SYS_H
  2. #define __SYS_H
  3. #include "stm32f4xx .h"
  4. //
  5. //
  6. //0,不支持ucos
  7. //1,支持ucos
  8. #define SYSTEM_SUPPORT_OS 0 //定义系统文件夹是否支持UCOS
  9. //位带操作,实现51类似的GPIO控制功能
  10. //具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).M4同M3类似,只是寄存器地址变了.
  11. //IO口操作宏定义
  12. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+ 0x2000000+((addr & 0xFFFFF)<< 5)+(bitnum<< 2))
  13. #define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
  14. #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
  15. //IO口地址映射
  16. #define GPIOA_ODR_Addr (GPIOA_BASE+ 20) //0x40020014
  17. #define GPIOB_ODR_Addr (GPIOB_BASE+ 20) //0x40020414
  18. #define GPIOC_ODR_Addr (GPIOC_BASE+ 20) //0x40020814
  19. #define GPIOD_ODR_Addr (GPIOD_BASE+ 20) //0x40020C14
  20. #define GPIOE_ODR_Addr (GPIOE_BASE+ 20) //0x40021014
  21. #define GPIOF_ODR_Addr (GPIOF_BASE+ 20) //0x40021414
  22. #define GPIOG_ODR_Addr (GPIOG_BASE+ 20) //0x40021814
  23. #define GPIOH_ODR_Addr (GPIOH_BASE+ 20) //0x40021C14
  24. #define GPIOI_ODR_Addr (GPIOI_BASE+ 20) //0x40022014
  25. #define GPIOA_IDR_Addr (GPIOA_BASE+ 16) //0x40020010
  26. #define GPIOB_IDR_Addr (GPIOB_BASE+ 16) //0x40020410
  27. #define GPIOC_IDR_Addr (GPIOC_BASE+ 16) //0x40020810
  28. #define GPIOD_IDR_Addr (GPIOD_BASE+ 16) //0x40020C10
  29. #define GPIOE_IDR_Addr (GPIOE_BASE+ 16) //0x40021010
  30. #define GPIOF_IDR_Addr (GPIOF_BASE+ 16) //0x40021410
  31. #define GPIOG_IDR_Addr (GPIOG_BASE+ 16) //0x40021810
  32. #define GPIOH_IDR_Addr (GPIOH_BASE+ 16) //0x40021C10
  33. #define GPIOI_IDR_Addr (GPIOI_BASE+ 16) //0x40022010
  34. //IO口操作,只对单一的IO口!
  35. //确保n的值小于16!
  36. #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
  37. #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
  38. #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
  39. #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
  40. #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
  41. #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
  42. #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
  43. #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
  44. #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
  45. #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
  46. #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
  47. #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
  48. #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
  49. #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
  50. #define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //输出
  51. #define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入
  52. #define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //输出
  53. #define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //输入
  54. //以下为汇编函数
  55. void WFI_SET(void); //执行WFI指令
  56. void INTX_DISABLE(void); //关闭所有中断
  57. void INTX_ENABLE(void); //开启所有中断
  58. void MSR_MSP(u32 addr); //设置堆栈地址
  59. #endif

26.sys.c


  
  1. #include "sys.h"
  2. //
  3. //
  4. //THUMB指令不支持汇编内联
  5. //采用如下方法实现执行汇编指令WFI
  6. __asm void WFI_SET( void)
  7. {
  8. WFI;
  9. }
  10. //关闭所有中断(但是不包括fault和NMI中断)
  11. __asm void INTX_DISABLE( void)
  12. {
  13. CPSID I
  14. BX LR
  15. }
  16. //开启所有中断
  17. __asm void INTX_ENABLE( void)
  18. {
  19. CPSIE I
  20. BX LR
  21. }
  22. //设置栈顶地址
  23. //addr:栈顶地址
  24. __asm void MSR_MSP( u32 addr)
  25. {
  26. MSR MSP, r0 //set Main Stack value
  27. BX r14
  28. }


下位机程序

27.  ui 界面代码:


  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ui version="4.0">
  3. <class>MainWindow </class>
  4. <widget class="QMainWindow" name="MainWindow">
  5. <property name="geometry">
  6. <rect>
  7. <x>0 </x>
  8. <y>0 </y>
  9. <width>1079 </width>
  10. <height>499 </height>
  11. </rect>
  12. </property>
  13. <property name="windowTitle">
  14. <string>MainWindow </string>
  15. </property>
  16. <widget class="QWidget" name="centralwidget">
  17. <widget class="QSplitter" name="splitter">
  18. <property name="geometry">
  19. <rect>
  20. <x>11 </x>
  21. <y>11 </y>
  22. <width>469 </width>
  23. <height>374 </height>
  24. </rect>
  25. </property>
  26. <property name="orientation">
  27. <enum>Qt::Horizontal </enum>
  28. </property>
  29. <widget class="QGroupBox" name="groupBox">
  30. <property name="title">
  31. <string>串口控制 </string>
  32. </property>
  33. <layout class="QVBoxLayout" name="verticalLayout">
  34. <item>
  35. <layout class="QHBoxLayout" name="horizontalLayout">
  36. <item>
  37. <widget class="QLabel" name="label">
  38. <property name="text">
  39. <string>串口号 </string>
  40. </property>
  41. </widget>
  42. </item>
  43. <item>
  44. <widget class="QComboBox" name="comboBox_portName"/>
  45. </item>
  46. </layout>
  47. </item>
  48. <item>
  49. <layout class="QHBoxLayout" name="horizontalLayout_2">
  50. <item>
  51. <widget class="QLabel" name="label_2">
  52. <property name="text">
  53. <string>波特率 </string>
  54. </property>
  55. </widget>
  56. </item>
  57. <item>
  58. <widget class="QComboBox" name="comboBox_BaudRate">
  59. <item>
  60. <property name="text">
  61. <string>9600 </string>
  62. </property>
  63. </item>
  64. <item>
  65. <property name="text">
  66. <string>115200 </string>
  67. </property>
  68. </item>
  69. </widget>
  70. </item>
  71. </layout>
  72. </item>
  73. <item>
  74. <layout class="QHBoxLayout" name="horizontalLayout_3">
  75. <item>
  76. <widget class="QLabel" name="label_3">
  77. <property name="text">
  78. <string>数据位 </string>
  79. </property>
  80. </widget>
  81. </item>
  82. <item>
  83. <widget class="QComboBox" name="comboBox_DataBits">
  84. <item>
  85. <property name="text">
  86. <string>8 </string>
  87. </property>
  88. </item>
  89. </widget>
  90. </item>
  91. </layout>
  92. </item>
  93. <item>
  94. <layout class="QHBoxLayout" name="horizontalLayout_4">
  95. <item>
  96. <widget class="QLabel" name="label_4">
  97. <property name="text">
  98. <string>校验位 </string>
  99. </property>
  100. </widget>
  101. </item>
  102. <item>
  103. <widget class="QComboBox" name="comboBox_Parity">
  104. <item>
  105. <property name="text">
  106. <string>无校验 </string>
  107. </property>
  108. </item>
  109. </widget>
  110. </item>
  111. </layout>
  112. </item>
  113. <item>
  114. <layout class="QHBoxLayout" name="horizontalLayout_5">
  115. <item>
  116. <widget class="QLabel" name="label_5">
  117. <property name="text">
  118. <string>停止位 </string>
  119. </property>
  120. </widget>
  121. </item>
  122. <item>
  123. <widget class="QComboBox" name="comboBox_StopBits">
  124. <item>
  125. <property name="text">
  126. <string>1 </string>
  127. </property>
  128. </item>
  129. </widget>
  130. </item>
  131. </layout>
  132. </item>
  133. <item>
  134. <widget class="QPushButton" name="pushButton_open">
  135. <property name="text">
  136. <string>打开串口 </string>
  137. </property>
  138. </widget>
  139. </item>
  140. <item>
  141. <widget class="QPushButton" name="pushButton_led">
  142. <property name="text">
  143. <string>打开小灯 </string>
  144. </property>
  145. </widget>
  146. </item>
  147. <item>
  148. <widget class="QPushButton" name="pushButton_beep">
  149. <property name="text">
  150. <string>打开蜂鸣器 </string>
  151. </property>
  152. </widget>
  153. </item>
  154. <item>
  155. <widget class="QPushButton" name="pushButton">
  156. <property name="text">
  157. <string>获取温湿度数据 </string>
  158. </property>
  159. </widget>
  160. </item>
  161. </layout>
  162. </widget>
  163. <widget class="QGroupBox" name="groupBox_data">
  164. <property name="enabled">
  165. <bool>false </bool>
  166. </property>
  167. <property name="title">
  168. <string>串口数据 </string>
  169. </property>
  170. <layout class="QVBoxLayout" name="verticalLayout_4">
  171. <item>
  172. <widget class="QGroupBox" name="groupBox_3">
  173. <property name="title">
  174. <string>接收数据 </string>
  175. </property>
  176. <layout class="QVBoxLayout" name="verticalLayout_2">
  177. <item>
  178. <widget class="QTextBrowser" name="textBrowser_read"/>
  179. </item>
  180. </layout>
  181. </widget>
  182. </item>
  183. <item>
  184. <widget class="QGroupBox" name="groupBox_4">
  185. <property name="title">
  186. <string>发送数据 </string>
  187. </property>
  188. <layout class="QVBoxLayout" name="verticalLayout_3">
  189. <item>
  190. <layout class="QHBoxLayout" name="horizontalLayout_6">
  191. <item>
  192. <widget class="QLabel" name="label_6">
  193. <property name="text">
  194. <string>内容: </string>
  195. </property>
  196. </widget>
  197. </item>
  198. <item>
  199. <widget class="QPushButton" name="pushButton_send">
  200. <property name="text">
  201. <string>发送 </string>
  202. </property>
  203. </widget>
  204. </item>
  205. </layout>
  206. </item>
  207. <item>
  208. <widget class="QLineEdit" name="lineEdit_send"/>
  209. </item>
  210. </layout>
  211. </widget>
  212. </item>
  213. </layout>
  214. </widget>
  215. </widget>
  216. <widget class="QListWidget" name="listWidget">
  217. <property name="geometry">
  218. <rect>
  219. <x>490 </x>
  220. <y>0 </y>
  221. <width>251 </width>
  222. <height>381 </height>
  223. </rect>
  224. </property>
  225. </widget>
  226. <widget class="QDial" name="dial">
  227. <property name="geometry">
  228. <rect>
  229. <x>850 </x>
  230. <y>120 </y>
  231. <width>171 </width>
  232. <height>201 </height>
  233. </rect>
  234. </property>
  235. </widget>
  236. </widget>
  237. <widget class="QMenuBar" name="menubar">
  238. <property name="geometry">
  239. <rect>
  240. <x>0 </x>
  241. <y>0 </y>
  242. <width>1079 </width>
  243. <height>26 </height>
  244. </rect>
  245. </property>
  246. </widget>
  247. <widget class="QStatusBar" name="statusbar"/>
  248. </widget>
  249. <resources/>
  250. <connections/>
  251. </ui>

28. mainwindow.h


  
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. /***** 串口模块 ******/
  5. #include <QSerialPort> //串口类
  6. #include <QSerialPortInfo> //串口属性类 { 获取系统可用的串口 }
  7. QT_BEGIN_NAMESPACE
  8. namespace Ui { class MainWindow; }
  9. QT_END_NAMESPACE
  10. class MainWindow : public QMainWindow
  11. {
  12. Q_OBJECT
  13. public:
  14. MainWindow(QWidget *parent = nullptr);
  15. ~ MainWindow();
  16. public:
  17. void GetSystenSerilPort(); /*** 获取系统可用串口列表,并打印到UI界面 ***/
  18. private:
  19. Ui::MainWindow *ui;
  20. QSerialPort *SerialPort; /** 串口类 **/
  21. QString data11;
  22. public slots:
  23. void slot_pushButton_open();
  24. void slot_pushButton_send();
  25. void slot_SerialPort_readyRead();
  26. private slots:
  27. void on_pushButton_led_clicked();
  28. void on_pushButton_beep_clicked();
  29. void on_pushButton_clicked();
  30. void on_dial_valueChanged(int value);
  31. };
  32. #endif // MAINWINDOW_H

29. mainwindow.cpp


  
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QDebug>
  4. MainWindow:: MainWindow(QWidget *parent)
  5. : QMainWindow(parent)
  6. , ui(new Ui::MainWindow)
  7. {
  8. ui -> setupUi(this);
  9. /*** 申请串口类对象空间 ****/
  10. SerialPort = new QSerialPort(this);
  11. /*** 类构造时就获取系统可用串口列表 ***/
  12. GetSystenSerilPort();
  13. /*** 连接槽函数 ****/
  14. connect(ui ->pushButton_open, SIGNAL( clicked( bool)),this, SLOT( slot_pushButton_open()));
  15. connect(SerialPort, SIGNAL( readyRead()),this, SLOT( slot_SerialPort_readyRead()));
  16. connect(ui ->pushButton_send, SIGNAL( clicked( bool)),this, SLOT( slot_pushButton_send()));
  17. }
  18. void MainWindow:: slot_pushButton_send()
  19. {
  20. QString text = ui ->lineEdit_send -> text();
  21. SerialPort -> write(text. toUtf8());
  22. }
  23. void MainWindow:: slot_SerialPort_readyRead()
  24. {
  25. QByteArray data = SerialPort -> readAll();
  26. ui ->textBrowser_read -> append(data);
  27. QString a= QString(data);
  28. if(a== "\r" || a== "\n")
  29. {
  30. data11. clear();
  31. return;
  32. }
  33. data11+=a;
  34. if(data11. size()>= 7)
  35. {
  36. ui ->listWidget -> clear();
  37. ui ->listWidget -> addItem(data11);
  38. data11=data11. right( 2);
  39. QString kk= QString( "温度: ")+data11;
  40. ui ->listWidget -> addItem(kk);
  41. data11. clear();
  42. }
  43. }
  44. #include <QMessageBox> /*** 标准对话框 ****/
  45. void MainWindow:: slot_pushButton_open()
  46. {
  47. /******* 设置串口属性 ******/
  48. SerialPort -> setPortName(ui ->comboBox_portName -> currentText()); //设置串口号
  49. SerialPort -> setBaudRate(ui ->comboBox_BaudRate -> currentText(). toInt()); //设置波特率
  50. if(ui ->comboBox_DataBits -> currentText() == "8"){
  51. SerialPort -> setDataBits(QSerialPort::Data8); //设置数据位为8位
  52. }
  53. if(ui ->comboBox_Parity -> currentText() == "无校验"){
  54. SerialPort -> setParity(QSerialPort::NoParity); //设置校验位为无校验
  55. }
  56. if(ui ->comboBox_StopBits -> currentText() == "1"){
  57. SerialPort -> setStopBits(QSerialPort::OneStop); //设置停止位为1位
  58. }
  59. /***** 打开串口 ****/
  60. bool ok = false;
  61. if(ui ->pushButton_open -> text() == "打开串口")
  62. {
  63. ok = SerialPort -> open(QIODevice::ReadWrite);
  64. if(ok == true) //串口打开成功
  65. {
  66. ui ->groupBox_data -> setEnabled( true);
  67. ui ->pushButton_open -> setText( "关闭串口");
  68. }
  69. else
  70. {
  71. QMessageBox:: warning(this, "警告", "串口打开失败,请检查串口参数或串口已被占用");
  72. return ;
  73. }
  74. } else
  75. {
  76. SerialPort -> close(); //关闭串口
  77. ui ->pushButton_open -> setText( "打开串口");
  78. ui ->groupBox_data -> setEnabled( false);
  79. }
  80. }
  81. MainWindow::~ MainWindow()
  82. {
  83. delete ui;
  84. }
  85. void MainWindow:: GetSystenSerilPort()
  86. {
  87. QList<QSerialPortInfo> list_SerialPortInfo = QSerialPortInfo:: availablePorts(); /*** 获取系统可用串口列表 ***/
  88. ui ->comboBox_portName -> clear(); /** 清空 串口号的下拉选项框 ***/
  89. for(QSerialPortInfo value : list_SerialPortInfo)
  90. {
  91. ui ->comboBox_portName -> addItem(value. portName()); /*** 将串口名称添加到 UI 的串口号下拉选项框中 ***/
  92. }
  93. }
  94. void MainWindow:: on_pushButton_led_clicked() //打开小灯
  95. {
  96. if(ui ->pushButton_led -> text() == "打开小灯")
  97. {
  98. qDebug()<< "打开小灯发送成功";
  99. ui ->pushButton_led -> setText( "关闭小灯");
  100. QString text= QString( "1\r\n");
  101. SerialPort -> write(text. toLocal8Bit());
  102. }
  103. else
  104. {
  105. qDebug()<< "关闭小灯发送成功";
  106. ui ->pushButton_led -> setText( "打开小灯");
  107. QString text= QString( "2\r\n");
  108. SerialPort -> write(text. toLocal8Bit());
  109. }
  110. }
  111. void MainWindow:: on_pushButton_beep_clicked() //打开蜂鸣器
  112. {
  113. if(ui ->pushButton_beep -> text() == "打开蜂鸣器")
  114. {
  115. qDebug()<< "打开蜂鸣器发送成功";
  116. ui ->pushButton_beep -> setText( "关闭蜂鸣器");
  117. QString text= QString( "3\r\n");
  118. SerialPort -> write(text. toLocal8Bit());
  119. }
  120. else
  121. {
  122. qDebug()<< "关闭蜂鸣器发送成功";
  123. QString text= QString( "4\r\n");
  124. SerialPort -> write(text. toLocal8Bit());
  125. ui ->pushButton_beep -> setText( "打开蜂鸣器");
  126. }
  127. }
  128. void MainWindow:: on_pushButton_clicked() //获取温湿度
  129. {
  130. qDebug()<< "获取温湿度发送成功";
  131. QString text= QString( "5\r\n");
  132. SerialPort -> write(text. toLocal8Bit());
  133. }
  134. void MainWindow:: on_dial_valueChanged(int value)
  135. {
  136. qDebug()<< "旋钮转动";
  137. QString text= QString( "0") + QString:: number(value) + QString( "\r\n");
  138. SerialPort -> write(text. toLocal8Bit());
  139. }

mian.cpp


  
  1. #include "mainwindow.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. MainWindow w;
  7. w. show();
  8. return a. exec();
  9. }


转载:https://blog.csdn.net/she666666/article/details/128476474
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场