HDQ.c
上传用户:xs588588
上传日期:2021-03-30
资源大小:242k
文件大小:4k
源码类别:

DSP编程

开发平台:

C/C++

  1. #include <msp430x14x.h>
  2. #include "HDQ.h"
  3. // 定义工作的状态
  4. enum
  5. {
  6.   imWrite,
  7.   imWriteE,
  8.   imRead,
  9.   imReadE,
  10.   imDelay
  11. };
  12. // 定义全局变量
  13. // 中断服务程序的模式
  14. static unsigned char ISRMode;
  15. // 接收到的数据
  16. static unsigned char Xfer;
  17. // 发送数据的位数
  18. static unsigned char BitCnt;
  19. // 记录时间戳
  20. static unsigned int Ticks;
  21. // Break及恢复
  22. static void HDQBreak(void)
  23. {
  24. // 设置Break的时间
  25. TACCR0 = TAR + tBreak * 2;
  26. // 复位OUT0,使能中断
  27. TACCTL0 = OUTMOD_0 + CCIE;
  28. // 设置中断服务为延时模式
  29. ISRMode = imDelay;
  30. // 进入低功耗模式
  31. _BIS_SR(LPM0_bits);
  32. // 设置Break的恢复时间
  33. TACCR0 += tBR;
  34. // 设置OUT0,使能中断
  35. TACCTL0 = OUTMOD_0 + OUT + CCIE;
  36. // 进入低功耗模式
  37. _BIS_SR(LPM0_bits);
  38. }
  39. // HDQ总线的写操作
  40. static void HDQBasicWrite(unsigned char Data)
  41. {
  42. Xfer = Data;
  43. // 复位OUT0
  44. TACCTL0 = OUTMOD_0; 
  45. TACCR0 = TAR;
  46. // 位开始的时间戳
  47. Ticks = TACCR0; 
  48. // 设置低电平的时间
  49. if (Xfer & 0x01)    
  50. // “1”
  51. TACCR0 += tHW1;                             
  52. else
  53. // “0”
  54. TACCR0 += tHW0;
  55. // Toggle OUT0,中断使能
  56. TACCTL0 = OUTMOD_4 + CCIE;
  57. // 设置传输的位数为8
  58. BitCnt = 8; 
  59. // 中断服务为写模式
  60. ISRMode = imWrite; 
  61. // 进入低功耗模式
  62. _BIS_SR(LPM0_bits);
  63. }
  64. void HDQSetup(void)
  65. {
  66. // P1.1为输出
  67. P1DIR |= BIT1;
  68. // 选择TA0功能
  69. P1SEL |= 0x02;
  70. }
  71. // HDQ的写操作
  72. void HDQWrite(unsigned char Addr, unsigned char Data)
  73. {
  74. // 选择SMCLK为时钟源,连续模式
  75. TACTL = TASSEL_2 + MC_2;
  76. // P1.1为输出
  77. P1DIR |= 0x02; 
  78. // 总线Break
  79. HDQBreak();
  80. // 发送地址,确保R/W比特为0
  81. HDQBasicWrite(Addr | 0x80);
  82. // 延时
  83. // 设置时间
  84. TACCR0 += tCYCH;
  85. // 设置OUT0,中断使能
  86. TACCTL0 = OUTMOD_0 + OUT + CCIE;
  87. // 设置中断服务为延时模式
  88. ISRMode = imDelay;
  89. // 进入低功耗
  90. _BIS_SR(LPM0_bits);
  91. // 写入数据
  92. HDQBasicWrite(Data);
  93. // P1.1为输入
  94. P1DIR &= ~0x02;
  95. // 停止Timer_A
  96. TACTL = 0;
  97. }
  98. // HDQ的读操作
  99. unsigned int HDQRead(unsigned char Addr)
  100. {
  101. // 选择SMCLK为时钟源,连续模式
  102. TACTL = TASSEL_2 + MC_2;
  103. // P1.1为输出
  104. P1DIR |= 0x02; 
  105. // 总线Break
  106. HDQBreak();
  107. // 发送地址
  108. HDQBasicWrite(Addr);
  109. // P1.1为输入
  110. P1DIR &= ~0x02;
  111. // 设置数据为8位
  112. BitCnt = 8;
  113. // 设置中断服务为读模式
  114. ISRMode = imRead;
  115. // 在P1.1管脚捕获下降沿
  116. TACCTL0 = CM_2 + CCIS_0 + SCCI + CAP + CCIE; 
  117. // 设置超时时间
  118. TACCR1 = TAR + tTO; 
  119. // 使能中断
  120. TACCTL1 = CCIE; 
  121. // 进入低功耗
  122. _BIS_SR(LPM0_bits); 
  123. // 停止Timer_A
  124. TACTL = 0;       
  125. // 判断数据是否有效
  126. if (BitCnt)
  127. return 0xffff;  
  128. else
  129. return Xfer;   
  130. }
  131. void Init_CLK(void)
  132. {
  133.     unsigned int i;
  134. //将寄存器的内容清零
  135. //XT2震荡器开启
  136. //LFTX1工作在低频模式
  137. //ACLK的分频因子为1
  138.     BCSCTL1 = 0X00;
  139.     do 
  140.     {
  141. // 清除OSCFault标志
  142. IFG1 &= ~OFIFG; 
  143. for (i = 0x20; i > 0; i--);                
  144.     }
  145.     while ((IFG1 & OFIFG) == OFIFG); 
  146.     BCSCTL2 = 0X00;
  147. //MCLK的时钟源为TX2CLK,分频因子为4
  148.     BCSCTL2 += SELM1 + DIVM_2;
  149. //SMCLK的时钟源为TX2CLK,分频因子为4
  150.     BCSCTL2 += SELS + DIVS_2;
  151. }
  152. interrupt [TIMERA0_VECTOR] void Timer_A0_ISR(void)
  153. {
  154. switch (ISRMode)
  155. {
  156. case imWrite :
  157. if (--BitCnt)
  158. {
  159. // 设置时间
  160. TACCR0 = Ticks + tCYCH;
  161. ISRMode = imWriteE;
  162. }
  163. else
  164. {
  165. // 设置OUT0,禁止中断
  166. TACCTL0 = OUTMOD_0 + OUT;
  167. // 返回激活状态
  168. _BIC_SR(LPM0_bits);
  169. }
  170. break;
  171. case imWriteE :
  172. // 位开始时间戳
  173. Ticks = TACCR0; 
  174. if ((Xfer >>= 1) & 0x01)
  175. // “1”
  176. TACCR0 += tHW1;
  177. else
  178. // “0” 
  179. TACCR0 += tHW0;
  180. ISRMode = imWrite;
  181. break;
  182. case imRead :
  183. // 停止超时
  184. TACCTL1 = 0;
  185. // 在位的中央采样
  186. TACCR0 += (tDW0 + tDW1) / 2;
  187. // 捕获模式
  188. TACCTL0 &= ~CAP;
  189. ISRMode = imReadE;
  190. break;
  191. case imReadE :
  192. Xfer >>= 1; 
  193. // 检查Timer_A的锁存
  194. if (TACCTL0 & SCCI) 
  195. Xfer |= 0x80;
  196. if (--BitCnt)
  197. {
  198. // 捕获模式
  199. TACCTL0 |= CAP;
  200. // 设置超时
  201. TACCR1 = TAR + tTO;
  202. // 使能中断
  203. TACCTL1 = CCIE;
  204. // 读模式
  205. ISRMode = imRead;
  206. }
  207. else
  208. {
  209. // 设置OUT0,禁止中断
  210. TACCTL0 = OUTMOD_0 + OUT;
  211. // 返回激活状态
  212. _BIC_SR(LPM0_bits);
  213. }
  214. break;
  215. case imDelay :
  216. // 禁止中断
  217. TACCTL0 &= ~CCIFG;        
  218. // 返回激活状态
  219. _BIC_SR(LPM0_bits);
  220. break;
  221. }
  222. }
  223. interrupt [TIMERA1_VECTOR] void Timer_A1_ISR(void)
  224. {
  225. if (TAIV == 0x02)
  226. {
  227. TACCTL0 = 0; 
  228. TACCTL1 = 0; 
  229. // 返回激活状态
  230. _BIC_SR(LPM0_bits);
  231. }
  232. }