大学生
最后登录1970-1-1
在线时间 小时
注册时间2014-6-3
|
找了一下,没有具体的关于串口半双工通信的帖子,我自己捣鼓了一天,发一下,帮我看看。
我用的是野火IOS-mini开发板(用了快三年了吧,屏都碎了)
首先,改一下初始化函数
直接改火哥的例程,把RX口去掉,反正也用不到,然后根据datasheet作一下寄存器配置,把USART_CR2寄存器的LINEN和CLKEN位和USART_CR3寄存器的SCEN和IREN位置零。
void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* config USART1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
/* USART1 GPIO config */
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
USART1->CR3 &= CR3_SCEN_Reset;
USART1->CR3 &= CR3_IREN_Reset;
USART1->CR2 &= CR2_LINEN_Reset;
USART1->CR2 &= CR2_CLKEN_Reset;
USART_HalfDuplexCmd( USART1, ENABLE);
/* USART1 mode config */
USART_InitStructure.USART_BaudRate = 115200;
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(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
单线半双方模式通过设置USART_CR3寄存器的HDSEL位选择。在这个模式里,下面的位必须保持清零状态:
● USART_CR2寄存器的LINEN和CLKEN位
● USART_CR3寄存器的SCEN和IREN位
USART可以配置成遵循单线半双工协议。在单线半双工模式下,TX和RX引脚在芯片内部互连。使用控制位”HALF DUPLEX SEL”(USART_CR3中的HDSEL位)选择半双工和全双工通信。
当HDSEL为’1’时
● RX不再被使用
● 当没有数据传输时,TX总是被释放。因此,它在空闲状态的或接收状态时表现为一个标准I/O口。这就意味该I/O在不被USART驱动时,必须配置成悬空输入(或开漏的输出高)。
除此以外,通信与正常USART模式类似。由软件来管理线上的冲突(例如通过使用一个中央仲裁器)。特别的是,发送从不会被硬件所阻碍。当TE位被设置时,只要数据一写到数据寄存器上,发送就继续。
这个“冲突管理”特别重要,我卡了蛮久的,一直32只能发数据不能接数据,看一下主函数:
int main(void)
{
/* USART1 config 115200 8-N-1 */
USART1_Config();
printf("\r\n 半双工实验 \r\n");
while(1)
{
USART1->CR1 |= 0x0004; //必须使能RE位,串口才能接收数据
scanf("%c",&ch);
USART1->CR1 &=~ 0x0004; //必须清零RE位,串口才能发送数据
if(ch=='1')
printf("\r\n 1 \r\n");
else
printf(" \r\n 0 \r\n");
printf("%c \n",ch);
printf("over ");
}
}
我用的是接收使能位来管理冲突,据说还能用TE位,我没有试过。这样就OK啦,可以用32的串口半双工通信了,不过TTL转USB那里还有个问题,USB是全双工的,把PA9和PA10 短接就行了,就可以在电脑上看到了。
另外还有个问题,这里用scanf()函数获取数据的话需要发两个数程序才能继续运行,这个我不太懂,有知道的告诉我下。
(第一次发帖子,有神马错误一定要告诉我啊!!)
|
|