STM32 USART by DMA mode
前言:開始學USART+DMA的時候看到帖子《STM32 UART DMA實現未知數據長度接收》,覺得方法妙極了。此下出自此帖子——(整體的思路是這樣的,一開始設置好DMA接收,可以把緩衝區長度設置為幀最大長度,我們可以把RX連接到計時器的管腳輸入端,並且一開始設置輸入並且使能引腳下降沿中斷,當幀的第一個位元組發送時,因為起始位為低電平,空閒時UART為高電平,滿足條件,進入中斷,禁止中斷,並且在中斷中開啟計時器,該計時器工作在重定模式,上升沿重定,並且設置好計時器輸出比較值為超時時間,比如20ms,這樣,在傳輸後面位元組時,肯定會有高低電平出現,即便是傳輸的是0x00,0xFF,雖然UART資料區不變,但是都為1,或都為0,但是因為起始位為低電平,停止位是高電平,所以肯定會有上升沿,計時器會一直復位,輸出計時器的計數器一直到達不了輸出比較值,當一幀傳輸結束後,定時在最後一個位元組重定後,由於沒有資料繼續到達,無法重定,則計數器就能計到輸出比較值,這時發出中斷,在計時器中斷中可以計算出接收資料的長度,並且通知外部資料已經接收完畢。)
今天我在工作中調通了另一種USART+DMA接收未知數據長度的接收,使用的是USRAT空閒匯流排中斷接收,這種方法也在網站上比較多見,以前沒試過,今天才知道如此的爽,另外我使用DMA發送USART資料替代了以前的查詢法發送,發現更加爽了。其速度快了很多,尤其是在大量資料傳輸與發送的時候其優勢更加明顯。
我舉個例子:1、後臺資料->USART1-> USART2->其它設備,其它設備資料->USART2-> USART1->後臺,這兩個資料過程也可能同時進行。
2、由於硬體的限制,USART1和USART2的傳輸串列傳輸速率不一樣,比如USART1使用GPRS通信,USART2使用短距離無線通訊;或者USART1使用乙太網通信,USART2使用485匯流排通信。
由於在寢室只有筆記型電腦,只有一個串口轉USB,沒辦法實現兩個串口之間的資料轉發了,只好實現串口各自的資料轉發。
現在我把我實現的過程簡單描述一下:
1、 初始化設置:USART1_RX+DMA1_ Channel5,USART2_RX+DMA1_ Channel6,USART1_TX+DMA1_ Channel4,USART2_TX+DMA1_ Channel7(具體設置請看套裝程式)。
2、 當資料發送給USART1接收完畢時候會引起USART1的串口匯流排中斷,計算DMA1_ Channel5記憶體陣列剩餘容量,得到接收的字元長度。將接收的字元複製給DMA1_ Channel4記憶體陣列,啟動DMA1_ Channel4通道傳輸資料,(傳輸完成需要關閉。)下一次資料接收可以在啟動DMA1_ Channel4時候就開始,不需要等待DMA1_ Channel4資料傳輸完成。但是上一次DMA1_ Channel4完成之前,不可以將資料複製給DMA1_ Channel4記憶體陣列,會沖掉以前資料。
3、 USART2類同USART1。
呵呵,下麵貼程式:
我舉個例子:1、後臺資料->USART1-> USART2->其它設備,其它設備資料->USART2-> USART1->後臺,這兩個資料過程也可能同時進行。
2、由於硬體的限制,USART1和USART2的傳輸串列傳輸速率不一樣,比如USART1使用GPRS通信,USART2使用短距離無線通訊;或者USART1使用乙太網通信,USART2使用485匯流排通信。
由於在寢室只有筆記型電腦,只有一個串口轉USB,沒辦法實現兩個串口之間的資料轉發了,只好實現串口各自的資料轉發。
現在我把我實現的過程簡單描述一下:
1、 初始化設置:USART1_RX+DMA1_ Channel5,USART2_RX+DMA1_ Channel6,USART1_TX+DMA1_ Channel4,USART2_TX+DMA1_ Channel7(具體設置請看套裝程式)。
2、 當資料發送給USART1接收完畢時候會引起USART1的串口匯流排中斷,計算DMA1_ Channel5記憶體陣列剩餘容量,得到接收的字元長度。將接收的字元複製給DMA1_ Channel4記憶體陣列,啟動DMA1_ Channel4通道傳輸資料,(傳輸完成需要關閉。)下一次資料接收可以在啟動DMA1_ Channel4時候就開始,不需要等待DMA1_ Channel4資料傳輸完成。但是上一次DMA1_ Channel4完成之前,不可以將資料複製給DMA1_ Channel4記憶體陣列,會沖掉以前資料。
3、 USART2類同USART1。
呵呵,下麵貼程式:
1.[ IO口定義:]
2. void GPIO_Configuration(void)
3. {
4. GPIO_InitTypeDef GPIO_InitStructure;
5. /* 第1步:打開GPIO和USART部件的時鐘 */
6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
8. /* 第2步:將USART Tx的GPIO配置為推挽複用模式 */
9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
10. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
11. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
12. GPIO_Init(GPIOA, &GPIO_InitStructure);
13. /* 第3步:將USART Rx的GPIO配置為浮空輸入模式
14. 由於CPU復位後,GPIO缺省都是浮空輸入模式,因此下面這個步驟不是必須的
15. 但是,我還是建議加上便於閱讀,並且防止其它地方修改了這個口線的設置參數
16. */
17. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
18.
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
19.
GPIO_Init(GPIOA, &GPIO_InitStructure);
20. /* 第1步:打開GPIO和USART2部件的時鐘 */
21. //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
22. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,
ENABLE);
23. /* 第2步:將USART2 Tx的GPIO配置為推挽複用模式 */
24.
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
25.
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
26. GPIO_InitStructure.GPIO_Speed
= GPIO_Speed_50MHz;
27. GPIO_Init(GPIOA,
&GPIO_InitStructure);
28. /* 第3步:將USART2 Rx的GPIO配置為浮空輸入模式
29.
由於CPU復位後,GPIO缺省都是浮空輸入模式,因此下面這個步驟不是必須的
30.
但是,我還是建議加上便於閱讀,並且防止其它地方修改了這個口線的設置參數
31. */
32.
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
33. GPIO_InitStructure.GPIO_Mode
= GPIO_Mode_IN_FLOATING;
34.
GPIO_Init(GPIOA, &GPIO_InitStructure);
35.
/* 第3步已經做了,因此這步可以不做
36.
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
37. */
38.
GPIO_Init(GPIOA, &GPIO_InitStructure);
39. }
40. [串口初始化:]
41. void USART_Configuration(void)
42. {
43.
USART_InitTypeDef USART_InitStructure;
44.
/* 第4步:配置USART參數
45.
- BaudRate = 115200 baud
46.
- Word Length = 8 Bits
47.
- One Stop Bit
48.
- No parity
49.
- Hardware flow control disabled (RTS and CTS signals)
50.
- Receive and transmit enabled
51.
*/
52.
USART_InitStructure.USART_BaudRate = 19200;
53.
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
54.
USART_InitStructure.USART_StopBits = USART_StopBits_1;
55.
USART_InitStructure.USART_Parity = USART_Parity_No;
56.
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
57.
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
58.
USART_Init(USART1, &USART_InitStructure);
59.
//空閒中斷
60.
USART_ITConfig(USART1, USART_IT_IDLE , ENABLE);
61. /* 第5步:使能 USART, 配置完畢 */
62.
USART_Cmd(USART1, ENABLE);
63. /* CPU的小缺陷:串口配置好,如果直接Send,則第1個位元組發送不出去
64.
如下語句解決第1個位元組無法正確發送出去的問題 */
65.
USART_ClearFlag(USART1, USART_FLAG_TC); /* 清發送外城標誌,Transmission Complete flag */
66.
USART_InitStructure.USART_BaudRate = 9600;
67.
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
68.
USART_InitStructure.USART_StopBits = USART_StopBits_1;
69.
USART_InitStructure.USART_Parity = USART_Parity_No;
70.
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
71.
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
72.
USART_Init(USART2, &USART_InitStructure);
73.
USART_ITConfig(USART2, USART_IT_IDLE , ENABLE);//開啟空閒,幀錯,雜訊,校驗錯中斷
74.
USART_Cmd(USART2, ENABLE);
75. /* CPU的小缺陷:串口配置好,如果直接Send,則第1個位元組發送不出去
76.
如下語句解決第1個位元組無法正確發送出去的問題 */
77.
USART_ClearFlag(USART2, USART_FLAG_TC); /* 清發送外城標誌,Transmission Complete flag */
78. }
79.[ DMA配置:]
80. void DMA_Configuration(void)
81. {
82. DMA_InitTypeDef
DMA_InitStructure;
83. /* DMA clock enable */
84. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,
ENABLE);//DMA1
85. /* DMA1 Channel4
(triggered by USART1 Tx event) Config */
86. DMA_DeInit(DMA1_Channel4);
87. DMA_InitStructure.DMA_PeripheralBaseAddr
= 0x40013804;
88. DMA_InitStructure.DMA_MemoryBaseAddr
= (uint32_t)USART1_SEND_DATA;
89. DMA_InitStructure.DMA_DIR
= DMA_DIR_PeripheralDST;
90. DMA_InitStructure.DMA_BufferSize
= 512;
91. DMA_InitStructure.DMA_PeripheralInc
= DMA_PeripheralInc_Disable;
92. DMA_InitStructure.DMA_MemoryInc
= DMA_MemoryInc_Enable;
93. DMA_InitStructure.DMA_PeripheralDataSize
= DMA_PeripheralDataSize_Byte;
94. DMA_InitStructure.DMA_MemoryDataSize
= DMA_MemoryDataSize_Byte;
95. DMA_InitStructure.DMA_Mode
= DMA_Mode_Circular;
96. DMA_InitStructure.DMA_Priority
= DMA_Priority_High;
97. DMA_InitStructure.DMA_M2M
= DMA_M2M_Disable;
98. DMA_Init(DMA1_Channel4,
&DMA_InitStructure);
99. DMA_ITConfig(DMA1_Channel4,
DMA_IT_TC, ENABLE);
100. DMA_ITConfig(DMA1_Channel4,
DMA_IT_TE, ENABLE);
101. /* Enable USART1 DMA TX
request */
102. USART_DMACmd(USART1,
USART_DMAReq_Tx, ENABLE);
103. DMA_Cmd(DMA1_Channel4,
DISABLE);
104. /* DMA1 Channel5
(triggered by USART2 Tx event) Config */
105. DMA_DeInit(DMA1_Channel7);
106. DMA_InitStructure.DMA_PeripheralBaseAddr
= 0x40004404;
107. DMA_InitStructure.DMA_MemoryBaseAddr
= (uint32_t)USART2_SEND_DATA;
108. DMA_InitStructure.DMA_DIR
= DMA_DIR_PeripheralDST;
109. DMA_InitStructure.DMA_BufferSize
= 512;
110. DMA_InitStructure.DMA_PeripheralInc
= DMA_PeripheralInc_Disable;
111. DMA_InitStructure.DMA_MemoryInc
= DMA_MemoryInc_Enable;
112. DMA_InitStructure.DMA_PeripheralDataSize
= DMA_PeripheralDataSize_Byte;
113. DMA_InitStructure.DMA_MemoryDataSize
= DMA_MemoryDataSize_Byte;
114. DMA_InitStructure.DMA_Mode
= DMA_Mode_Circular;
115. DMA_InitStructure.DMA_Priority
= DMA_Priority_High;
116. DMA_InitStructure.DMA_M2M
= DMA_M2M_Disable;
117. DMA_Init(DMA1_Channel7,
&DMA_InitStructure);
118. DMA_ITConfig(DMA1_Channel7,
DMA_IT_TC, ENABLE);
119. DMA_ITConfig(DMA1_Channel7,
DMA_IT_TE, ENABLE);
120. /* Enable USART1 DMA TX
request */
121. USART_DMACmd(USART2,
USART_DMAReq_Tx, ENABLE);
122. DMA_Cmd(DMA1_Channel7,
DISABLE);
123. /* DMA1 Channel5
(triggered by USART1 Rx event) Config */
124. DMA_DeInit(DMA1_Channel5);
125. DMA_InitStructure.DMA_PeripheralBaseAddr
= 0x40013804;
126. DMA_InitStructure.DMA_MemoryBaseAddr
= (uint32_t)USART1_RECEIVE_DATA;
127. DMA_InitStructure.DMA_DIR
= DMA_DIR_PeripheralSRC;
128. DMA_InitStructure.DMA_BufferSize
= 512;
129. DMA_InitStructure.DMA_PeripheralInc
= DMA_PeripheralInc_Disable;
130. DMA_InitStructure.DMA_MemoryInc
= DMA_MemoryInc_Enable;
131. DMA_InitStructure.DMA_PeripheralDataSize
= DMA_PeripheralDataSize_Byte;
132. DMA_InitStructure.DMA_MemoryDataSize
= DMA_MemoryDataSize_Byte;
133. DMA_InitStructure.DMA_Mode
= DMA_Mode_Circular;
134. DMA_InitStructure.DMA_Priority
= DMA_Priority_High;
135. DMA_InitStructure.DMA_M2M
= DMA_M2M_Disable;
136. DMA_Init(DMA1_Channel5,
&DMA_InitStructure);
137. DMA_ITConfig(DMA1_Channel5,
DMA_IT_TC, ENABLE);
138. DMA_ITConfig(DMA1_Channel5,
DMA_IT_TE, ENABLE);
139.
140. /* Enable USART1 DMA RX
request */
141. USART_DMACmd(USART1,
USART_DMAReq_Rx, ENABLE);
142. DMA_Cmd(DMA1_Channel5,
ENABLE);
143. /* DMA1 Channel6
(triggered by USART1 Rx event) Config */
144. DMA_DeInit(DMA1_Channel6);
145. DMA_InitStructure.DMA_PeripheralBaseAddr
= 0x40004404;
146. DMA_InitStructure.DMA_MemoryBaseAddr
= (uint32_t)USART2_RECEIVE_DATA;
147. DMA_InitStructure.DMA_DIR
= DMA_DIR_PeripheralSRC;
148. DMA_InitStructure.DMA_BufferSize
= 512;
149. DMA_InitStructure.DMA_PeripheralInc
= DMA_PeripheralInc_Disable;
150. DMA_InitStructure.DMA_MemoryInc
= DMA_MemoryInc_Enable;
151. DMA_InitStructure.DMA_PeripheralDataSize
= DMA_PeripheralDataSize_Byte;
152. DMA_InitStructure.DMA_MemoryDataSize
= DMA_MemoryDataSize_Byte;
153. DMA_InitStructure.DMA_Mode
= DMA_Mode_Circular;
154. DMA_InitStructure.DMA_Priority
= DMA_Priority_Medium;
155. DMA_InitStructure.DMA_M2M
= DMA_M2M_Disable;
156. DMA_Init(DMA1_Channel6,
&DMA_InitStructure);
157. DMA_ITConfig(DMA1_Channel6,
DMA_IT_TC, ENABLE);
158. DMA_ITConfig(DMA1_Channel6,
DMA_IT_TE, ENABLE);
159. /* Enable USART2 DMA RX
request */
160. USART_DMACmd(USART2,
USART_DMAReq_Rx, ENABLE);
161. DMA_Cmd(DMA1_Channel6,
ENABLE);
162. }
163. [ 中斷優先順序配置:]
164. void NVIC_Configuration(void)
165. {
166. NVIC_InitTypeDef
NVIC_InitStructure;
167. /* Configure one bit for
preemption priority */
168. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
169. /* Enable the USART1
Interrupt */
170. NVIC_InitStructure.NVIC_IRQChannel
= USART1_IRQn;
171. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
= 2;
172. NVIC_InitStructure.NVIC_IRQChannelSubPriority
= 1;
173. NVIC_InitStructure.NVIC_IRQChannelCmd
= ENABLE;
174. NVIC_Init(&NVIC_InitStructure);
175. /* Enable the USART2
Interrupt */
176. NVIC_InitStructure.NVIC_IRQChannel
= USART2_IRQn;
177. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
= 2;
178. NVIC_InitStructure.NVIC_IRQChannelSubPriority
= 2;
179. NVIC_InitStructure.NVIC_IRQChannelCmd
= ENABLE;
180. NVIC_Init(&NVIC_InitStructure);
181. //Enable DMA Channel4
Interrupt
182. NVIC_InitStructure.NVIC_IRQChannel
= DMA1_Channel4_IRQn;
183. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
= 1;
184. NVIC_InitStructure.NVIC_IRQChannelSubPriority
= 1;
185. NVIC_InitStructure.NVIC_IRQChannelCmd
= ENABLE;
186. NVIC_Init(&NVIC_InitStructure);
187. //Enable DMA Channel7
Interrupt
188. NVIC_InitStructure.NVIC_IRQChannel
= DMA1_Channel7_IRQn;
189. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
= 1;
190. NVIC_InitStructure.NVIC_IRQChannelSubPriority
= 2;
191. NVIC_InitStructure.NVIC_IRQChannelCmd
= ENABLE;
192. NVIC_Init(&NVIC_InitStructure);
193. /*Enable DMA Channel5
Interrupt */
194. NVIC_InitStructure.NVIC_IRQChannel
= DMA1_Channel5_IRQn;
195. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
= 2;
196. NVIC_InitStructure.NVIC_IRQChannelSubPriority
= 0;
197. NVIC_InitStructure.NVIC_IRQChannelCmd
= ENABLE;
198. NVIC_Init(&NVIC_InitStructure);
199. /*Enable DMA Channel6
Interrupt */
200. NVIC_InitStructure.NVIC_IRQChannel
= DMA1_Channel6_IRQn;
201. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
= 2;
202. NVIC_InitStructure.NVIC_IRQChannelSubPriority
= 1;
203. NVIC_InitStructure.NVIC_IRQChannelCmd
= ENABLE;
204. NVIC_Init(&NVIC_InitStructure);
205. }
206. 陣列定義,含義如題名:
207. u8 USART1_SEND_DATA[512];
208. u8 USART2_SEND_DATA[512];
209. u8 USART1_RECEIVE_DATA[512];
210. u8 USART2_RECEIVE_DATA[512];
211. u8 USART1_TX_Finish=1;// USART1發送完成標誌量
212. u8 USART2_TX_Finish=1; // USART2發送完成標誌量
213. [ USART1中斷服務函數]
214. void USART1_IRQHandler(void)
215. {
216. u16
DATA_LEN;
217. u16 i;
218.
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)//如果為空閒匯流排中斷
219. {
220.
DMA_Cmd(DMA1_Channel5, DISABLE);//關閉DMA,防止處理其間有資料
221.
//USART_RX_STA = USART1->SR;//先讀SR,然後讀DR才能清除
222.
//USART_RX_STA = USART1->DR;
223.
DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel5);
224.
if(DATA_LEN > 0)
225.
{
226.
while(USART1_TX_Finish==0)//等待資料傳輸完成才下一次
227.
{
228.
;
229.
}
230.
//將資料送DMA存儲位址
231.
for(i=0;i
232.
{
233.
USART1_SEND_DATA[i]=USART1_RECEIVE_DATA[i];
234.
}
235.
//USART用DMA傳輸替代查詢方式發送,克服被高優先順序中斷而產生丟幀現象。
236.
DMA_Cmd(DMA1_Channel4, DISABLE); //改變datasize前先要禁止通道工作
237.
DMA1_Channel4->CNDTR=DATA_LEN; //DMA1,傳輸資料量
238.
USART1_TX_Finish=0;//DMA傳輸開始標誌量
239.
DMA_Cmd(DMA1_Channel4, ENABLE);
240.
}
241.
//DMA_Cmd(DMA1_Channel5, DISABLE);//關閉DMA,防止處理其間有資料
242.
DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 |
DMA1_FLAG_TE5 | DMA1_FLAG_HT5);//清標誌
243.
DMA1_Channel5->CNDTR = 512;//重裝填
244.
DMA_Cmd(DMA1_Channel5, ENABLE);//處理完,重開DMA
245.
//讀SR後讀DR清除Idle
246.
i = USART1->SR;
247.
i = USART1->DR;
248. }
249.
if(USART_GetITStatus(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE) !=
RESET)//出錯
250. {
251.
USART_ClearITPendingBit(USART1, USART_IT_PE | USART_IT_FE
| USART_IT_NE);
252. }
253.
USART_ClearITPendingBit(USART1, USART_IT_TC);
254.
USART_ClearITPendingBit(USART1, USART_IT_IDLE);
255. }
256. [USART2中斷服務函數]
257. void USART2_IRQHandler(void)
258. {
259. u16
DATA_LEN;
260. u16 i;
261.
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) //如果為空閒匯流排中斷
262. {
263.
DMA_Cmd(DMA1_Channel6, DISABLE);//關閉DMA,防止處理其間有資料
264.
//USART_RX_STA = USART1->SR;//先讀SR,然後讀DR才能清除
265.
//USART_RX_STA = USART1->DR;
266.
DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel6);
267.
if(DATA_LEN > 0)
268.
{
269.
while(USART2_TX_Finish==0)//等待資料完成才下一次
270.
{
271.
;
272.
}
273.
//將資料送DMA存儲位址
274.
for(i=0;i
275.
{
276.
USART2_SEND_DATA[i]=USART2_RECEIVE_DATA[i];
277.
}
278.
//USART用DMA傳輸替代查詢方式發送,克服被高優先順序中斷而產生丟幀現象。
279.
DMA_Cmd(DMA1_Channel7, DISABLE); //改變datasize前先要禁止通道工作
280.
DMA1_Channel7->CNDTR=DATA_LEN; //DMA1,傳輸資料量
281.
USART2_TX_Finish=0;//DMA傳輸開始標誌量
282.
DMA_Cmd(DMA1_Channel7, ENABLE);
283.
}
284.
//DMA_Cmd(DMA1_Channel5, DISABLE);//關閉DMA,防止處理其間有資料
285.
DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 |
DMA1_FLAG_TE6 | DMA1_FLAG_HT6);//清標誌
286.
DMA1_Channel6->CNDTR = 512;//重裝填
287.
DMA_Cmd(DMA1_Channel6, ENABLE);//處理完,重開DMA
288.
//讀SR後讀DR清除Idle
289.
i = USART2->SR;
290.
i = USART2->DR;
291. }
292.
if(USART_GetITStatus(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE) !=
RESET)//出錯
293. {
294.
USART_ClearITPendingBit(USART2, USART_IT_PE | USART_IT_FE
| USART_IT_NE);
295. }
296.
USART_ClearITPendingBit(USART2, USART_IT_TC);
297.
USART_ClearITPendingBit(USART2, USART_IT_IDLE);
298. }
299. [ DMA1_Channel5中斷服務函數]
300. void DMA1_Channel5_IRQHandler(void)
301. {
302. DMA_ClearITPendingBit(DMA1_IT_TC5);
303. DMA_ClearITPendingBit(DMA1_IT_TE5);
304. DMA_Cmd(DMA1_Channel5,
DISABLE);//關閉DMA,防止處理其間有資料
305. DMA1_Channel5->CNDTR =
580;//重裝填
306. DMA_Cmd(DMA1_Channel5,
ENABLE);//處理完,重開DMA
307. }
308. [ DMA1_Channel6中斷服務函數 ]
309. void DMA1_Channel6_IRQHandler(void)
310. {
311. DMA_ClearITPendingBit(DMA1_IT_TC6);
312. DMA_ClearITPendingBit(DMA1_IT_TE6);
313. DMA_Cmd(DMA1_Channel6,
DISABLE);//關閉DMA,防止處理其間有資料
314. DMA1_Channel6->CNDTR =
580;//重裝填
315. DMA_Cmd(DMA1_Channel6, ENABLE);//處理完,重開DMA
316. }
317. [ DMA1_Channel4中斷服務函數 ]
318. //USART1使用DMA發資料中斷服務程式
319. void DMA1_Channel4_IRQHandler(void)
320. {
321. DMA_ClearITPendingBit(DMA1_IT_TC4);
322. DMA_ClearITPendingBit(DMA1_IT_TE4);
323. DMA_Cmd(DMA1_Channel4,
DISABLE);//關閉DMA
324. USART1_TX_Finish=1;//置DMA傳輸完成
325. }
326. [ DMA1_Channel7中斷服務函數]
327. //USART2使用DMA發資料中斷服務程式
328. void DMA1_Channel7_IRQHandler(void)
329. {
330. DMA_ClearITPendingBit(DMA1_IT_TC7);
331. DMA_ClearITPendingBit(DMA1_IT_TE7);
332.
DMA_Cmd(DMA1_Channel7, DISABLE);//關閉DMA
333. USART2_TX_Finish=1;//置DMA傳輸完成
334. }
複製代碼
沒有留言:
張貼留言