[Cortex-M0技术交流] 菜鸟学习M0第十九帖——DS18B20

[复制链接]
4330|6
 楼主| lixiaoxu2meng 发表于 2011-9-28 16:35 | 显示全部楼层 |阅读模式
本帖最后由 lixiaoxu2meng 于 2011-9-28 16:38 编辑

直接上代码
main函数
  1. #include "includes.h" //包含所需的头文件
  2. /*************************************************************************************
  3. ** Function name: main
  4. ** Descriptions: DS18B20实时采集温度 并通过数码管显示出来
  5. ** input parameters: 无
  6. ** output parameters: 无
  7. ** Returned value: 无
  8. *************************************************************************************/
  9. int main (void)
  10. {
  11. Set_System();
  12. while(1)
  13. {
  14. value = read_temp();
  15. delay_ms(1000);
  16. }
  17. }
hw_config函数
  1. #include "includes.h" //包含所需的头文件
  2. //DQ对应引脚 GPB4
  3. #define DQ_STATE DrvGPIO_GetBit(E_GPB,4) //DQ引脚的状态
  4. #define CLR_DQ DrvGPIO_ClrBit(E_GPB, 4) //DQ引脚输出低电平
  5. #define SET_DQ DrvGPIO_SetBit(E_GPB, 4) //DQ引脚输出高电平
  6. #define DQ_OUTPUT DrvGPIO_Open(E_GPB, 4, E_IO_OUTPUT) //DQ引脚设置为输出
  7. #define DQ_INPUT DrvGPIO_Open(E_GPB, 4, E_IO_INPUT) //DQ引脚设置为输入 一边读取该引脚的状态
  8. /*************************************************************************************
  9. ** Function name: Set_System
  10. ** Descriptions: 1ms(晶振为12MHZ)延时子程序
  11. ** input parameters: count
  12. ** output parameters: 无
  13. ** Returned value: 无
  14. *************************************************************************************/
  15. void Set_System(void)
  16. {
  17. RCC_Configuration(); //配置系统时钟

  18. GPIO_Configuration(); //配置GPIO

  19. TIMER_Configuration(); //配置TIMER

  20. }
  21. /*************************************************************************************
  22. ** Function name: RCC_Configuration
  23. ** Descriptions: 系统时钟源设置
  24. ** input parameters: none
  25. ** output parameters: none
  26. ** Returned value: none
  27. *************************************************************************************/
  28. void RCC_Configuration(void)
  29. {
  30. UNLOCKREG(); // 对写保护位操作时 需要一次向0x50000 0100写入 0x59,0x16,0x88,
  31. DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);//与其 SYSCLK->WRCON.XTL12M_EN = 1; 等同
  32. // PWRCON寄存器(这些寄存器在上电复位到用户解锁定之前是锁定的)除了 BIT[6]位其他位都受写保护
  33. // 解除这些需要向 0x50000 0100写入 0x59,0x16,0x88,
  34. // 令PWRCON寄存器的BITP[0]为1(即设定12M外部晶振)
  35. delay_ms(100); //while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);//等待外部12MHZ晶振就绪
  36. LOCKREG(); // 向“0x5000_0100”写入任何值,就可以重锁保护寄存器
  37. }
  38. /*************************************************************************************
  39. ** Function name: GPIO_Configuration
  40. ** Descriptions: GPIO配置
  41. ** input parameters: none
  42. ** output parameters: none
  43. ** Returned value: none
  44. *************************************************************************************/
  45. void GPIO_Configuration()
  46. {
  47. DrvGPIO_Open( E_GPA, 2, E_IO_OUTPUT );//数码管段选
  48. DrvGPIO_Open( E_GPA, 3, E_IO_OUTPUT );
  49. DrvGPIO_Open( E_GPA, 4, E_IO_OUTPUT );
  50. DrvGPIO_Open( E_GPA, 5, E_IO_OUTPUT );
  51. DrvGPIO_Open( E_GPA, 6, E_IO_OUTPUT );
  52. DrvGPIO_Open( E_GPA, 7, E_IO_OUTPUT );
  53. DrvGPIO_Open( E_GPA, 8, E_IO_OUTPUT );
  54. DrvGPIO_Open( E_GPA, 9, E_IO_OUTPUT );
  55. DrvGPIO_Open( E_GPC, 14, E_IO_OUTPUT );//数码管位选
  56. DrvGPIO_Open( E_GPC, 15, E_IO_OUTPUT );
  57. DrvGPIO_Open( E_GPC, 6, E_IO_OUTPUT );
  58. DrvGPIO_Open( E_GPC, 7, E_IO_OUTPUT );
  59. }
  60. /*************************************************************************************
  61. ** Function name: TIMER_Configuration
  62. ** Descriptions: TIMER配置
  63. ** input parameters: none
  64. ** output parameters: none
  65. ** Returned value: none
  66. *************************************************************************************/
  67. void TIMER_Configuration()
  68. {
  69. DrvTIMER_Init(); //初始化定时器
  70. DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC, 0); //使用外设时注意必须设置该外设的时钟 设置TIMER的时钟源为外部12MHZ
  71. DrvTIMER_Open(E_TMR0,1000,E_PERIODIC_MODE); //设定定时器 tick 周期并且启动定时器:定时器通道 TMR0 每秒1000次 周期模式
  72. DrvTIMER_SetTimerEvent(E_TMR0,5,(TIMER_CALLBACK) Timer0_Callback,0); //安装一个定时处理事件到 timer0, timer1, timer2, timer3通道
  73. DrvTIMER_EnableInt(E_TMR0); //使能定时器中断
  74. DrvTIMER_Start(E_TMR0); //定时器timer0开始计数
  75. }
  76. /*************************************************************************************
  77. ** Function name: Timer0_Callback
  78. ** Descriptions: 定时处理事件
  79. ** input parameters: none
  80. ** output parameters: none
  81. ** Returned value: none
  82. *************************************************************************************/
  83. void Timer0_Callback (void)
  84. {
  85. static uint8_t count= 0;
  86. static uint8_t i,xx[4];
  87. uint32_t data;
  88. uint16_t ValueBuff ;

  89. ValueBuff = value*10;
  90. count++;
  91. if(count >= 5)
  92. count = 1;
  93. for(i=0;i<4;i++)
  94. {
  95. xx = ValueBuff%10;
  96. ValueBuff = ValueBuff/10;
  97. }
  98. switch(count)
  99. {
  100. case 1:
  101. DrvGPIO_SetBit(E_GPC,14);
  102. DrvGPIO_ClrBit(E_GPC,15);
  103. DrvGPIO_ClrBit(E_GPC,6);
  104. DrvGPIO_ClrBit(E_GPC,7);
  105. data= 0xC6 ; //显示C
  106. data =data <<2;
  107. GPIOA->DOUT = data;
  108. break;
  109. case 2:
  110. DrvGPIO_SetBit(E_GPC,15);
  111. DrvGPIO_ClrBit(E_GPC,14);
  112. DrvGPIO_ClrBit(E_GPC,6);
  113. DrvGPIO_ClrBit(E_GPC,7);
  114. data = Table[xx[1]]<<2;
  115. GPIOA->DOUT = data;
  116. break;
  117. case 3:
  118. DrvGPIO_SetBit(E_GPC,7);
  119. DrvGPIO_ClrBit(E_GPC,14);
  120. DrvGPIO_ClrBit(E_GPC,15);
  121. DrvGPIO_ClrBit(E_GPC,6);
  122. data = Table[xx[2]]<<2;
  123. GPIOA->DOUT = data;
  124. DrvGPIO_ClrBit(E_GPA,9); //显示小数点
  125. break;
  126. case 4:
  127. DrvGPIO_SetBit(E_GPC,6);
  128. DrvGPIO_ClrBit(E_GPC,14);
  129. DrvGPIO_ClrBit(E_GPC,15);
  130. DrvGPIO_ClrBit(E_GPC,7);
  131. data = Table[xx[3]]<<2;
  132. GPIOA->DOUT = data;
  133. break;
  134. default:break;
  135. }
  136. }
  137. /*************************************************************************************
  138. ** Function name: ds1820reset
  139. ** Descriptions: DS18B20初始化
  140. ** input parameters: none
  141. ** output parameters: none
  142. ** Returned value: none
  143. *************************************************************************************/
  144. void ds1820reset()
  145. {
  146. /*step1:首先主机产生RESET脉冲*/
  147. DQ_OUTPUT; //将DQ引脚设置为输出
  148. CLR_DQ; //DQ引脚输出低电平(即拉低至少为480us)
  149. delay_ds18b20(300); //精确延时 大于480us
  150. SET_DQ; //DQ引脚输出高电平(即释放数据线)
  151. /*step2:等待15~60us后 DS18B20将把数据线拉低60~240us 以作为应答*/
  152. DQ_INPUT; //将DQ引脚设置为输入
  153. while(DQ_STATE); //如果没有应答也一直等待(注意在while里可加上超时处理 以免通信出错 而造成死机)
  154. while(!DQ_STATE); //应答后等待(注意在while里可加上超时处理 以免通信出错 而造成死机)
  155. /*step3:释放数据线,并延时480us(因为等待与应答必须大于480us才算整个初始化完成)*/
  156. SET_DQ; //DQ引脚输出高电平(即释放数据线)
  157. delay_ds18b20(300); //为了保证初始化完成 在延时480us
  158. }
  159. /*************************************************************************************
  160. ** Function name: ds1820rd
  161. ** Descriptions: DS18B20 读数据
  162. ** input parameters: none
  163. ** output parameters: none
  164. ** Returned value: none
  165. *************************************************************************************/
  166. uint8_t ds1820rd()//读数据
  167. {
  168. uint8_t i=0;
  169. uint8_t dat = 0;
  170. for (i=8;i>0;i--)
  171. {
  172. DQ_OUTPUT;//将DQ引脚设置为输出
  173. CLR_DQ;//DQ引脚输出低电平(即拉低)
  174. delay_ds18b20(2);
  175. dat>>=1;
  176. SET_DQ;//DQ引脚输出高电平
  177. DQ_INPUT;//将DQ引脚设置为输入
  178. delay_ds18b20(2);
  179. if(DQ_STATE)
  180. dat|=0x80;
  181. delay_ds18b20(40);//大于60us
  182. }
  183. DQ_OUTPUT;
  184. SET_DQ; //放数据线
  185. return(dat);
  186. }
  187. /*************************************************************************************
  188. ** Function name: ds1820rd
  189. ** Descriptions: DS18B20 写数据
  190. ** input parameters: none
  191. ** output parameters: none
  192. ** Returned value: none
  193. *************************************************************************************/
  194. void ds1820wr(uint8_t wdata)//写数据
  195. {
  196. uint8_t i=0;
  197. for (i=8; i>0; i--)
  198. {
  199. DQ_OUTPUT; //将DQ引脚设置为输出
  200. CLR_DQ; //DQ引脚输出低电平(小于15us )
  201. delay_ds18b20(2); //延时小于15us
  202. if(wdata&0x01) SET_DQ; //DQ引脚输出高电平
  203. else CLR_DQ; //DQ引脚输出低电平
  204. delay_ds18b20(40); //延时大于60us
  205. SET_DQ; //DQ引脚输出高电平
  206. wdata>>=1;
  207. }
  208. }
  209. /*************************************************************************************
  210. ** Function name: read_temp
  211. ** Descriptions: 读取温度值并将读到的温度进行处理
  212. ** input parameters: none
  213. ** output parameters: none
  214. ** Returned value: none
  215. *************************************************************************************/
  216. uint16_t read_temp()//读取温度值并转换
  217. {
  218. uint8_t a,b;
  219. temp_value = 0;
  220. ds1820reset();
  221. ds1820wr(0xcc);//跳过读序列号
  222. ds1820wr(0x44);//启动温度转换
  223. ds1820reset();
  224. ds1820wr(0xcc);//跳过读序列号
  225. ds1820wr(0xbe);//读取温度
  226. a=ds1820rd();
  227. b=ds1820rd();
  228. temp_value=b;
  229. temp_value<<=8;
  230. temp_value=temp_value|a;
  231. if(temp_value<0x0fff) //如果为正数
  232. mark=0;
  233. else //如果为负数
  234. {
  235. temp_value=~temp_value+1;
  236. mark=1;
  237. }
  238. temp_value=temp_value*(0.625);//温度值扩大10倍,精确到1位小数
  239. return(temp_value);
  240. }
  241. /*************************************************************************************
  242. ** Function name: delay_ms
  243. ** Descriptions: 1ms(晶振为12MHZ)延时子程序
  244. ** input parameters: count
  245. ** output parameters: 无
  246. ** Returned value: 无
  247. *************************************************************************************/
  248. void delay_ms(uint32_t count)
  249. {
  250. uint32_t i,j;
  251. for(i=count;i>0;i--)
  252. for(j=2395;j>0;j--);
  253. }
  254. /*************************************************************************************
  255. ** Function name: delay_ms
  256. ** Descriptions: 大约40us(晶振为12MHZ)延时子程序
  257. ** input parameters: count
  258. ** output parameters: 无
  259. ** Returned value: 无
  260. *************************************************************************************/
  261. void delay_ds18b20(uint32_t count)
  262. {
  263. uint32_t i,j;
  264. for(i=count;i>0;i--)
  265. for(j=2;j>0;j--);
  266. }
hw_config头文件
  1. #ifndef __HW_CONFIG_H__
  2. #define __HW_CONFIG_H__
  3. void Set_System(void);
  4. void RCC_Configuration(void);
  5. void GPIO_Configuration(void);
  6. void TIMER_Configuration(void);
  7. void Timer0_Callback (void);
  8. void delay_ms(uint32_t count);
  9. void delay_ds18b20(uint32_t count);
  10. void ds1820reset(void);
  11. uint8_t ds1820rd(void);
  12. void ds1820wr(uint8_t wdata);
  13. uint16_t read_temp(void);
  14. #endif

明天再上图
工程

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
hotpower 发表于 2011-9-28 17:58 | 显示全部楼层
很好!和烈火一样,都是用的延时。
不过助学板的ds18b20是接在uart1上的,
故可以用“单总线硬件控制器”的思路编写程序,
这样利用波特率产生的精准宽度以避免了编写软件延时。
楼主可以参考老师的look之ds18b20的例程编写。
两种风格不一样的感受。后者不需要任何精准的延时。
hotpower 发表于 2011-9-28 18:14 | 显示全部楼层
可以看到单总线的读写需要独占,有些不合理,当然短时间不会太影响其他任务。新唐的uart比较多,浪费了不如做控制器。
 楼主| lixiaoxu2meng 发表于 2011-9-28 18:51 | 显示全部楼层
恩 有时间 研究下老师说的方法
lr441227048 发表于 2011-11-21 18:33 | 显示全部楼层
好东西,支持
hotpower 发表于 2011-11-21 19:41 | 显示全部楼层
李老师look中有一个ds18b20的例程。
wgchou 发表于 2012-4-18 20:57 | 显示全部楼层
正需要。感谢分享了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

1679

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部