很棒的下午社区!
有人已经工作过 SoftUart? 我需要帮助。 我将在 频率为8MHz 的 MSP430FR5994微控制器上实现115200Hz 的 SoftUart。 TXD 位于 P4.1、RXD 位于 P4.2。
它已经发送了字符串、但在接收时它只接收1。 感谢你的帮助。
以下是我的代码。
// main.c ----------------------------
#include
#include
#include "UART.h"
int main (空)
{
//停止看门狗计时器
WDTCTL = WDTPW + WDTHOLD; //停止 WDT
SetClockMHz();
ConfigurePORTS();
PM5CTL0 &=~LOCKLPM5; //禁用 GPIO 上电
_enable_interrupt (); //启用全局中断
UART_PUTs (" MSP430 SoftUart 115200\n"r);
while (1)
{
if (UART_getc (&Data)){
UART_putc (数据);
_DELAY_CYCLES (4000000);
}
}
}
// uart.h ----------------------------------------
#ifndef __UART_H
#define _UART_H
#include
#include
#定义 TXD BIT1 // TXD em P4.1
# define RXD BIT2 // RXD em P4.2
# define F8MHz 8000000 // CPU 8MHz
# define BAUDRATE 115200 // taxa de transmissão
# define BIT_TIME (F8MHz/BAUDRATE) // Tempo de 位
# define half_bit_time (bit_time/2) // Tempo de meio 位
静态易失性 uint8_t bitCount=0; // Contagem DE 位
静态无符号 int TXByte; // Valor envado por UART_putc ()
静态无符号 int RXByte; // Valor recibido
静态 bool 接收= false; //状态调整
静态 bool 接收器接收= false; // um 字节 e recibido
/*初始化软 UART */
void SetClockMHz (void);
void ConfigurePORTS (void);
bool UART_getc (uint8_t * c);
void UART_putc (uint8_t c);
void UART_puts (const char *str);
#endif /* UART_H_*/
// uart.c ----------------------------------
#include
#include
#include "UART.h"
/*初始化软 UART */
空 SetClockMHz (空)
{
// DCO ~8MHz 的启动时钟系统
CSCTL0 = CSKEY; //解锁 CS 寄存器
CSCTL1 = DCOFSEL_6; //将 DCO 设置为8MHz
CSCTL2 = SELA_VLOCLK|SELESS__DCOCLK|SELM_DCOCLK;
CSCTL3 = DIVA__1|DIVS_1|DIVM_1; //设置所有分频器
CSCTL0_H = 0; //锁定 CS 寄存器
返回;
}
空配置 PORTS (空)
{
//配置 TXD
P4DIR |= TXD; // P4.1 TX 输出
//配置 RXD
P4DIR &=~RXD; // P4.2 RX 输入
P4OUT |= RXD; //设置内部上拉电阻器
P4REN |= RXD; //启用内部上拉电阻器
P4IES |= RXD; //高电平到低电平转换
P4IFG &=~RXD; //清除中断标志
P4IE |= RXD; //中断使能
返回;
}
/*从 UART 非阻塞式读取一个字符。*/
bool UART_getc (uint8_t * c)
{
如果(!已接收){返回 false;}
*c = RXByte;
接收器= false;
返回 true;
}
/*将一个字符串写入 UART 阻塞*/
void UART_putc (uint8_t c)
{
TXByte = c;
while (isReceiving); //等待 RX 完成
位计数= 0xA; //加载位计数器,开始+ 8位+停止
TXByte |= 0x100; //向 TXByte 添加停止位
TXByte = TXByte << 1; //添加起始位0
TA0CTL = tassel_SMCLK + MC_Continous;// SMCLK/1 +连续模式
TA0CCR0 = TA0R; //获取当前计时器计数
TA0CCR0 +=位时间; //将偏移添加到 TA0CCR0
TA0CCTL0 = CCIS_0 + OUTMOD_0 + CCIE + OUT;//设置信号、启用中断
while (TA0CCTL0和 CCIE); //等待之前的 TX 完成
返回;
}
/*将字符串写入 UART 阻塞。 *
void UART_puts (const char * str){
if (* str!= 0) uart_putc (* str++);
while (* str!= 0) UART_putc (* str++);
返回;
}
Port4的/* ISR */
#pragma vector = Port4_vector
_interrupt void Port4_ISR (void)
{
isReceiving = true;
P4IE &=~RXD; //禁用中断 P4.2
P4IFG &=~RXD; //清除中断标志 P4.2
TA0CTL = tassel_SMCLK + MC__Continous;// SMCLK + Continuous Mode
TA0CCR0 = TA0R; //初始化 TA0CCR0
TA0CCR0 += HALF_BIT_TIME; //将偏移添加到 TA0CCR0
TA0CCTL0 = OUTMOD_1 + CCIE; //禁用 TX 并启用中断计时器
RXByte = 0x00; //初始化 RXByte
位计数= 0x9; //加载位计数器,8位+ 1起始
}
用于 TXD 和 RXD 的/* CCR0 ISR */
#pragma vector = TIMER0_A0_vector
_interrupt void Timer0_A0_ISR (void)
{
TA0CCR0 +=位时间; //将偏移添加到 TA0CCR0
if (!isReceiving){ //收发
如果(bitCount = 0){ //完成?
TA0CTL = tassel__SMCLK; // tassel_SMCLK,计时器关闭
TA0CCTL0 &=~CCIE; //禁用中断计时器
}
否则{
IF (TXByte & 0x01){P4OUT |= TXD;} // P4.1 = 1
否则{P4OUT &=~TXD;} // P4.1 = 0
TXByte >=1;
bitCount --;
}
}
否则{ //接收
如果(bitCount = 0){ //完成?
TA0CTL = tassel__SMCLK; // SMCLK,计时器关闭
TA0CCTL0 &=~CCIE; //禁用中断计时器
P4IE |= RXD; //中断使能 P4.2
isReceiving = false;
如果((RXByte & 0x201)== 0x200){ //验证起始位和停止位
RXByte >=1; //删除起始位
RXByte &= 0xFF; //删除停止位
接收器= true;
}
}
否则{
如果(P4IN & RXD){RXByte |= 0x400;} //如果位被置位?
RXByte >=1; //向下移动位
bitCount --;
}
}
}