stm32 串口通信

发布者:龙腾少年最新更新时间:2017-10-25 来源: eefocus关键字:stm32  串口通信 手机看文章 扫描二维码
随时随地手机看文章

这次讲讲利用串口收发中断来进行串口通讯。STM32 上为每个串口分配了一个中断。也就是说无论是发送完成还是收到数据或是数据溢出都产生同一个中断。程序需在中断处理函数中读取状态寄存器(USART_SR)来判断当前的是什么中断。下面的中断映像图给出了这些中断源是如何汇合成最终的中断信号的。图中也给出了如何控制每一个单独的中断源是否起作用。

另外,Cortex-M3 内核中还有个NVIC,可以控制这里的中断信号是否触发中断处理函数的执行,还有这些外部中断的级别。关于NVIC 可以参考《ARM CortexM3 权威指南》,里面讲解的非常详细。

简单的说,为了开启中断,我们需要如下的代码:


  1. NVIC_InitTypeDef NVIC_InitStructure;

  2. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

  3. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  4. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  5. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  6. NVIC_Init(&NVIC_InitStructure);

  7. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断

  8. USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断

这里多说一句,串口的发送中断有两个,分别是:

  1. l发送数据寄存器空中断(TXE)

  2. l发送完成中断(TC)

一般来说我们会使用发送数据寄存器空中断,用这个中断发送的效率会高一些。

中断处理函数的框架如下,如果检测到错误就清除错误,收到数了就处理。发完当前数据了就发下一个。


  1. void USART1_IRQHandler(void)

  2. {

  3. unsigned int data;

  4. if(USART1->SR & 0x0F)

  5. {

  6. // See if we have some kind of error, Clear interrupt

  7. data = USART1->DR;

  8. }

  9. else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag

  10. {

  11. data = USART1->DR;

  12. // 对收到的数据进行处理,或者干些其他的事

  13. }

  14. else if(USART1->SR & USART_FLAG_TXE)

  15. {

  16. { // 可以发送数据了,如果没有数据需要发送,就在这里关闭发送中断

  17. USART1->DR = something; // Yes, Send character

  18. }

  19. }

  20. }


下面给一个利用环形缓冲区的串口驱动程序。


  1. #ifndef _COM_BUFFERED_H_

  2. #define _COM_BUFFERED_H_

  3. #define COM1 0

  4. #define COM2 1

  5. #define COM_RX_BUF_SIZE 64

  6. #define COM_TX_BUF_SIZE 64

  7. #define COM_NO_ERR 0

  8. #define COM_BAD_CH 1

  9. #define COM_RX_EMPTY 2

  10. #define COM_TX_FULL 3

  11. #define COM_TX_EMPTY 4

  12. unsigned char COMGetCharB (unsigned char ch, unsigned char *err);

  13. unsigned char COMPutCharB (unsigned char port, unsigned char c);

  14. void COMBufferInit (void);

  15. unsigned char COMBufferIsEmpty (unsigned char port);

  16. unsigned char COMBufferIsFull (unsigned char port);

  17. #endif



  1. #include "stm32f10x_usart.h"

  2. #include "com_buffered.h"

  3. #define OS_ENTER_CRITICAL() __set_PRIMASK(1)

  4. #define OS_EXIT_CRITICAL() __set_PRIMASK(0)

  5. static void COMEnableTxInt(unsigned char port)

  6. {

  7. static USART_TypeDef* map[2] = {USART1, USART2};

  8. USART_ITConfig(map[port], USART_IT_TXE, ENABLE);

  9. }

  10. typedef struct {

  11. short RingBufRxCtr;

  12. unsigned char *RingBufRxInPtr;

  13. unsigned char *RingBufRxOutPtr;

  14. unsigned char RingBufRx[COM_RX_BUF_SIZE];

  15. short RingBufTxCtr;

  16. unsigned char *RingBufTxInPtr;

  17. unsigned char *RingBufTxOutPtr;

  18. unsigned char RingBufTx[COM_TX_BUF_SIZE];

  19. } COM_RING_BUF;

  20. COM_RING_BUF COM1Buf;

  21. COM_RING_BUF COM2Buf;

  22. unsigned char COMGetCharB (unsigned char port, unsigned char *err)

  23. {

  24. // unsigned char cpu_sr;

  25. unsigned char c;

  26. COM_RING_BUF *pbuf;

  27. switch (port)

  28. {

  29. case COM1:

  30. pbuf = &COM1Buf;

  31. break;

  32. case COM2:

  33. pbuf = &COM2Buf;

  34. break;

  35. default:

  36. *err = COM_BAD_CH;

  37. return (0);

  38. }

  39. OS_ENTER_CRITICAL();

  40. if (pbuf->RingBufRxCtr > 0)

  41. {

  42. pbuf->RingBufRxCtr--;

  43. c = *pbuf->RingBufRxOutPtr++;

  44. if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE])

  45. {

  46. pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];

  47. }

  48. OS_EXIT_CRITICAL();

  49. *err = COM_NO_ERR;

  50. return (c);

  51. } else {

  52. OS_EXIT_CRITICAL();

  53. *err = COM_RX_EMPTY;

  54. c = 0;

  55. return (c);

  56. }

  57. }

  58. unsigned char COMPutCharB (unsigned char port, unsigned char c)

  59. {

  60. // unsigned char cpu_sr;

  61. COM_RING_BUF *pbuf;

  62. switch (port)

  63. {

  64. case COM1:

  65. pbuf = &COM1Buf;

  66. break;

  67. case COM2:

  68. pbuf = &COM2Buf;

  69. break;

  70. default:

  71. return (COM_BAD_CH);

  72. }

  73. OS_ENTER_CRITICAL();

  74. if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) {

  75. pbuf->RingBufTxCtr++;

  76. *pbuf->RingBufTxInPtr++ = c;

  77. if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE]) {

  78. pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];

  79. }

  80. if (pbuf->RingBufTxCtr == 1) {

  81. COMEnableTxInt(port);

  82. OS_EXIT_CRITICAL();

  83. } else {

  84. OS_EXIT_CRITICAL();

  85. }

  86. return (COM_NO_ERR);

  87. } else {

  88. OS_EXIT_CRITICAL();

  89. return (COM_TX_FULL);

  90. }

  91. }

  92. void COMBufferInit (void)

  93. {

  94. COM_RING_BUF *pbuf;

  95. pbuf = &COM1Buf;

  96. pbuf->RingBufRxCtr = 0;

  97. pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];

  98. pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];

  99. pbuf->RingBufTxCtr = 0;

  100. pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];

  101. pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];

  102. pbuf = &COM2Buf;

  103. pbuf->RingBufRxCtr = 0;

  104. pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];

  105. pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];

  106. pbuf->RingBufTxCtr = 0;

  107. pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];

  108. pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];

  109. }

  110. unsigned char COMBufferIsEmpty (unsigned char port)

  111. {

  112. // unsigned char cpu_sr;

  113. unsigned char empty;

  114. COM_RING_BUF *pbuf;

  115. switch (port)

  116. {

  117. case COM1:

  118. pbuf = &COM1Buf;

  119. break;

  120. case COM2:

  121. pbuf = &COM2Buf;

  122. break;

  123. default:

  124. return (1);

  125. }

  126. OS_ENTER_CRITICAL();

  127. if (pbuf->RingBufRxCtr > 0)

  128. {

  129. empty = 0;

  130. }

  131. else

  132. {

  133. empty = 1;

  134. }

  135. OS_EXIT_CRITICAL();

  136. return (empty);

  137. }

  138. unsigned char COMBufferIsFull (unsigned char port)

  139. {

  140. // unsigned char cpu_sr;

  141. char full;

  142. COM_RING_BUF *pbuf;

  143. switch (port)

  144. {

  145. case COM1:

  146. pbuf = &COM1Buf;

  147. break;

  148. case COM2:

  149. pbuf = &COM2Buf;

  150. break;

  151. default:

  152. return (1);

  153. }

  154. OS_ENTER_CRITICAL();

  155. if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) {

  156. full = 0;

  157. } else {

  158. full = 1;

  159. }

  160. OS_EXIT_CRITICAL();

  161. return (full);

  162. }

  163. // This function is called by the Rx ISR to insert a character into the receive ring buffer.

  164. static void COMPutRxChar (unsigned char port, unsigned char c)

  165. {

  166. COM_RING_BUF *pbuf;

  167. switch (port)

  168. {

  169. case COM1:

  170. pbuf = &COM1Buf;

  171. break;

  172. case COM2:

  173. pbuf = &COM2Buf;

  174. break;

  175. default:

  176. return;

  177. }

  178. if (pbuf->RingBufRxCtr < COM_RX_BUF_SIZE) {

  179. pbuf->RingBufRxCtr++;

  180. *pbuf->RingBufRxInPtr++ = c;

  181. if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE]) {

  182. pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];

  183. }

  184. }

  185. }

  186. // This function is called by the Tx ISR to extract the next character from the Tx buffer.

  187. // The function returns FALSE if the buffer is empty after the character is extracted from

  188. // the buffer. This is done to signal the Tx ISR to disable interrupts because this is the

  189. // last character to send.

  190. static unsigned char COMGetTxChar (unsigned char port, unsigned char *err)

  191. {

  192. unsigned char c;

  193. COM_RING_BUF *pbuf;

  194. switch (port)

  195. {

  196. case COM1:

  197. pbuf = &COM1Buf;

  198. break;

  199. case COM2:

  200. pbuf = &COM2Buf;

  201. break;

  202. default:

  203. *err = COM_BAD_CH;

  204. return (0);

  205. }

  206. if (pbuf->RingBufTxCtr > 0) {

  207. pbuf->RingBufTxCtr--;

  208. c = *pbuf->RingBufTxOutPtr++;

  209. if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE])

  210. {

  211. pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];

  212. }

  213. *err = COM_NO_ERR;

  214. return (c);

  215. } else {

  216. *err = COM_TX_EMPTY;

  217. return (0);

  218. }

  219. }

  220. void USART1_IRQHandler(void)

  221. {

  222. unsigned int data;

  223. unsigned char err;

  224. if(USART1->SR & 0x0F)

  225. {

  226. // See if we have some kind of error

  227. // Clear interrupt (do nothing about it!)

  228. data = USART1->DR;

  229. }

  230. else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag

  231. {

  232. data = USART1->DR;

  233. COMPutRxChar(COM1, data); // Insert received character into buffer

  234. }

  235. else if(USART1->SR & USART_FLAG_TXE)

  236. {

  237. data = COMGetTxChar(COM1, &err); // Get next character to send.

  238. if (err == COM_TX_EMPTY)

  239. { // Do we have anymore characters to send ?

  240. // No, Disable Tx interrupts

  241. //USART_ITConfig(USART1, USART_IT_TXE| USART_IT_TC, ENABLE);

  242. USART1->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;

  243. }

  244. else

  245. {

  246. USART1->DR = data; // Yes, Send character

  247. }

  248. }

  249. }

  250. void USART2_IRQHandler(void)

  251. {

  252. unsigned int data;

  253. unsigned char err;

  254. if(USART2->SR & 0x0F)

  255. {

  256. // See if we have some kind of error

  257. // Clear interrupt (do nothing about it!)

  258. data = USART2->DR;

  259. }

  260. else if(USART2->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag

  261. {

  262. data = USART2->DR;

  263. COMPutRxChar(COM2, data); // Insert received character into buffer

  264. }

  265. else if(USART2->SR & USART_FLAG_TXE)

  266. {

  267. data = COMGetTxChar(COM2, &err); // Get next character to send.

  268. if (err == COM_TX_EMPTY)

  269. { // Do we have anymore characters to send ?

  270. // No, Disable Tx interrupts

  271. //USART_ITConfig(USART2, USART_IT_TXE| USART_IT_TC, ENABLE);

  272. USART2->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;

  273. }

  274. else

  275. {

  276. USART2->DR = data; // Yes, Send character

  277. }

  278. }

  279. }


下面给个例子主程序,来演示如何使用上面的串口驱动代码。


  1. #include "misc.h"

  2. #include "stm32f10x.h"

  3. #include "com_buffered.h"

  4. void UART_PutStrB (unsigned char port, uint8_t *str)

  5. {

  6. while (0 != *str)

  7. {

  8. COMPutCharB(port, *str);

  9. str++;

  10. }

  11. }

  12. void USART1_Init(void)

  13. {

  14. GPIO_InitTypeDef GPIO_InitStructure;

  15. USART_InitTypeDef USART_InitStructure;

  16. NVIC_InitTypeDef NVIC_InitStructure;

  17. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

  18. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  19. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

  20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  21. GPIO_Init(GPIOA, &GPIO_InitStructure);

  22. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  23. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  24. GPIO_Init(GPIOA, &GPIO_InitStructure);

  25. USART_InitStructure.USART_BaudRate = 9600;

  26. USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  27. USART_InitStructure.USART_StopBits = USART_StopBits_1;

  28. USART_InitStructure.USART_Parity = USART_Parity_No;

  29. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  30. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  31. USART_Init(USART1, &USART_InitStructure );

  32. USART_Cmd(USART1, ENABLE);

  33. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

  34. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  35. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  36. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  37. NVIC_Init(&NVIC_InitStructure);

  38. }

  39. void USART2_Init(void)

  40. {

  41. GPIO_InitTypeDef GPIO_InitStructure;

  42. USART_InitTypeDef USART_InitStructure;

  43. NVIC_InitTypeDef NVIC_InitStructure;

  44. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);

  45. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  46. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

  47. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  48. GPIO_Init(GPIOD, &GPIO_InitStructure);

  49. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  50. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

  51. GPIO_Init(GPIOD, &GPIO_InitStructure);

  52. GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);

  53. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

  54. USART_InitStructure.USART_BaudRate = 9600;

  55. USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  56. USART_InitStructure.USART_StopBits = USART_StopBits_1;

  57. USART_InitStructure.USART_Parity = USART_Parity_No;

  58. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  59. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  60. USART_Init(USART2, &USART_InitStructure );

  61. USART_Cmd(USART2, ENABLE);

  62. NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

  63. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  64. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  65. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  66. NVIC_Init(&NVIC_InitStructure);

  67. }

  68. int main(void)

  69. {

  70. unsigned char c;

  71. unsigned char err;

  72. USART1_Init();

  73. USART2_Init();

  74. COMBufferInit();

  75. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

  76. USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

  77. UART_PutStrB(COM1, "Hello World!\n");

  78. for(;;)

  79. {

  80. c = COMGetCharB(COM1, &err);

  81. if(err == COM_NO_ERR)

  82. {

  83. COMPutCharB(COM1, c);

  84. }

  85. }

  86. }


关键字:stm32  串口通信 引用地址:stm32 串口通信

上一篇:STM32的GPIO中断例子
下一篇:STM32启动文件简单分析

推荐阅读最新更新时间:2024-03-16 15:41

基于CC2541蓝牙模块与单片机的串口通信
一、CC2541器件概述 CC2541是一款针对低能耗以及私有2.4GHz应用的功率优化的真正片载系统(SoC)解决方案。它使得使用低总体物料清单成本建立强健网络节点成为可能。CC2541将领先RF收发器的出色性能和一个业界标准的增强型8051MCU、系统内可编程闪存存储器、8kBRAM和很多其它功能强大的特性和外设组合在一起。CC2541非常适合应用于需要超低能耗的系统。这由多种不同的运行模式指定。运行模式间较短的转换时间进一步使低能耗变为可能 二、CC2541芯片的特性参数 CC2541是一款针对蓝牙低能耗以及私有2.4GHz应用的功率优化的真正片载系统(SoC)解决方案。它使得使用低总体物料清单成本建立强健网络节点成为可
[单片机]
基于CC2541蓝牙模块与单片机的<font color='red'>串口通信</font>
STM32串口接收中断溢出问题解决
在使用一个串口发数据的传感器过程中,发现程序第一次进入串口中断之后不再执行主函数的内容,中断中的内容也不执行。查询大量资料后发现:串口在接收数据过多时,会出现串口溢出错误,并进入溢出中断(ORE中断)。接下来是错误产生原因以及解决方法。 (1)什么是ORE中断?为什么会产生? 产生原因如上所述。 ORE标志位在USART_SR寄存器,但值得注意的是,当我们打开串口接收中断时,同时也就打开了ORE中断。 (2)如何解决? 看了上面的资料之后,我知道程序是死在了串口溢出中断。处理中断时,我首先想到的是清除这个中断标志位,但是遇到了很多麻烦。 清除ORE位的方法:顺序执行对USART_SR和USART_DR寄存器的读操作
[单片机]
STM32的下载及调试模式 接口
使用的最多的调试方式莫过于 JTAG 和SWD方式。 JTAG: JTAG (Joint Test Action Group,联合测试行动小组)是一种国际标准测试协议(IEEE 1149.1兼容),主要用于芯片内部测试。现在多数的高级器件都支持JTAG协议,如ARM、DSP、FPGA器件等。标准的JTAG接口是4线:TMS、 TCK、TDI、TDO,分别为模式选择、时钟、数据输入和数据输出线。相关JTAG引脚的定义为: TMS:模式选择,TMS用来设置JTAG接口处于某种特定的测试模式; TCK:时钟输入; TDI:数据输入,数据通过TDI引脚输入JTAG接口; TDO:数据输出,数据通过TDO引脚从JTAG接
[单片机]
stm32单片机GPIO端口的特点及应用解析
一、GPIO的综合描述 stm32每一个GPIO端口拥有2个32bits的configuration寄存器(GPIOx_CRL,GPIOx_CRH),2个32bits的数据寄存器(GPIOx_IDR,GPIOx_ODR),1个32bits的set/reset寄存器(GPIOx_BSRR),1个16bits的reset寄存器(GPIOx_BRR)和1个32bits的Lock寄存器(GPIOx_LCKR)。 (一)每一个IO引脚都可以使用软件配置为以下几种模式: 1. 浮空输入 2. 带上拉输入 3. 带下拉输入 4. 模拟输入 5. 开漏输出——(此模式可实现hotpower说的真双向IO) 6. 推挽输出 7. 复用功能的推挽
[单片机]
STM32单片机基础03——使用GPIO点亮一个LED
本篇文章主要介绍如何使用STM32CubeMX初始化STM32L431RCT6的GPIO,并点亮一个LED。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是 STM32L4的开发板(BearPi) : 软件准备 需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码; Keil MDK和串口助手的安装包都可以关注“小熊派开源社区”微信公众号,在资料教程一栏中可获取安装包。 2.生成MDK工程 选择芯片型号 打开STM32CubeMX,打开MCU选择器: 搜索并选中芯片STM32L431RCT6: 配置时钟源 如果选择使用外部高速
[单片机]
<font color='red'>STM32</font>单片机基础03——使用GPIO点亮一个LED
STM32学习之路之入门篇
2006年ARM公司推出了基于ARMV7架构的cortex系列的标准体系结构,以满足各种技术得不同性能要求,包含了A,R,M三个分工明确的系列 其中A系列面向复杂的尖端应用程序,用于运行开放式的复杂操作系统;R系列适合实时操作系统,M系列专门针对低成本的微控制领域。而我们今天要学习的STM32就是M3的处理器 STM32(M3)处理器的基本结构,基本结构如图所示,主要包括处理器核cortex-m3 core,NVIC,BUS MATRIS,FLASH转换,及断点单元,DWT,ITM,MPU,ETM,TPIU,ROM Table SW/SWJ-DP等模块,其中MPU和ETM单元是可选单元。 这些单元可分为内外两个层次,
[单片机]
<font color='red'>STM32</font>学习之路之入门篇
STM32的串口中断
总的来说,STM32单片机的串口还是很好理解的,编程也不算复杂。当然我更愿意希望其中断系统和51单片机一样的简单。 对于接收终端,就是RXNE了,这只在接收完成后才产生,在执行USART_ITConfig(USART1, USART_IT_RXNE, ENABLE)代码时不会进入ISR。但麻烦的就是发送有关的中断了:TXE或者TC,根据资料和测试的结果,TXE在复位后就是置1的,即在执行USART_ITConfig(USART1, USART_IT_TXE, ENABLE)后会立即产生中断请求。因此这造成一个麻烦的问题:如果没有真正的发送数据,TXE中断都会发生,而且没有休止,这将占用很大部分的CPU时间,甚至影响其他程
[单片机]
单片机串口通信控制步进电机
这是一个来自单片机开发板的源程序,原理图的下载地址: http://www.51hei.com/f/ks51.pdf 下面是源代码: /** ************************************************************************************************* * @file main.c * @author xr * @date 2014年3月18日20:00:03 * @note 步进电机的参数:减速比:1:64 步进角:5.625/64 启动频率: =550 启动时间最小:1.08ms * @brief 串口通信控制步进电
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved