usart.c
5.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include "dev.h"
#include "usart.h"
#include "timer.h"
#include "delay.h"
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 11
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
#endif
int fputc(int ch, FILE *f) //重定义fputc函数
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (uint8_t) ch;
return ch;
}
void USART1_Config(uint32_t bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //使能USART1时钟
GPIO_PinAFConfig(DBG_RXD_Port,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
GPIO_PinAFConfig(DBG_TXD_Port,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
GPIO_InitStructure.GPIO_Pin = DBG_RXD_Pin | DBG_TXD_Pin; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(DBG_RXD_Port,&GPIO_InitStructure); //初始化
USART_InitStructure.USART_BaudRate = bound; //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启相关中断
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 3; //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //初始化VIC寄存器
}
/****************************************************
*@brief: 串口5配置
*@param: uart 串口指针
* bound 串口波特率
*@retval: 无返回值
*****************************************************/
void UART5_Config(uint32_t bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);
GPIO_PinAFConfig(U485_RX_Port,GPIO_PinSource2,GPIO_AF_UART5);
GPIO_PinAFConfig(U485_TX_Port,GPIO_PinSource12,GPIO_AF_UART5);
GPIO_InitStructure.GPIO_Pin = U485_RX_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(U485_RX_Port,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = U485_TX_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(U485_TX_Port,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = EN_485_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(EN_485_Port,&GPIO_InitStructure);
UART5_Mode(RS485_READ);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(UART5, &USART_InitStructure);
USART_Cmd(UART5, ENABLE);
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
u32 UART_RX_CNT = 0;
u8 UART_RX_BUF[USART_REC_LEN] __attribute__ ((at(SRAM_EXT_ADDR))); //EXTI SRAM 200k
void UART5_IRQHandler(void)
{
if(USART_GetITStatus(UART5,USART_IT_RXNE) != RESET)
{
UART_RX_BUF[UART_RX_CNT++] = UART5->DR;
TIM3->CNT = 0;
TIM_Cmd(TIM3,ENABLE);
if(UART_RX_CNT == USART_REC_LEN) //防止溢出
{
UART_RX_CNT = 0;
}
}
USART_ClearITPendingBit(UART5, USART_IT_RXNE);
}
void UART5_Mode(mode status)
{
if(status == RS485_WRITE)
{
GPIO_SetBits(EN_485_Port,EN_485_Pin);
}
else if(status == RS485_READ)
{
GPIO_ResetBits(EN_485_Port,EN_485_Pin);
}
}
/***************************
*
*
*
****************************/
void Clear_Uart5_Cache(void)
{
memset(UART_RX_BUF,0,UART_RX_CNT);
UART_RX_CNT = 0;
}
void Uart5_Send(uint8_t *data,uint16_t length)
{
UART5_Mode(RS485_WRITE);
Tick_Delay_ms(1);
uint8_t i ;
for(i=0;i<length;i++)
{
USART_SendData(UART5,data[i]);
while((UART5->SR&0X40)==0);
}
Tick_Delay_ms(1);
UART5_Mode(RS485_READ);
}
#if 1
void USART1_IRQHandler(void) //串口1中断服务程序
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
#endif