搜索

[MCU] 求模拟串口程序

[复制链接]
111|37
 楼主 | 2020-11-19 23:16 | 显示全部楼层 |阅读模式

求模拟串口程序:MSP430F149,波特率9600,晶振32.768K
需要3个串口,只能模拟一个了,请大家帮忙

使用特权

评论回复
| 2020-11-19 23:21 | 显示全部楼层
我用I/O口模拟过串口,只做过发送,接收没做过。

使用特权

评论回复
| 2020-11-19 23:24 | 显示全部楼层
可以用定时器控制每位的时间

使用特权

评论回复
| 2020-11-19 23:28 | 显示全部楼层
嗯,也可以用示波器调试每位的时间。

使用特权

评论回复
| 2020-11-19 23:31 | 显示全部楼层

#include <msp430x44x.h>


//********************变量声明*****************************

#define TXD 0x01 //P1.0=TXD --->87

#define RXD 0x02 //P1.1=RXD --->86

#define OneBit 0x1A1

#define HalfBit 0xD0

unsigned int TxDate=0;

unsigned int RxDate=0;

unsigned char Count_R;

unsigned char Count_T;

unsigned char ParityBit=0;

unsigned char Movebit=0x01;

unsigned char verify_fault;

//*******************函数声明******************************

void init_DCO(void);

void init_TimerA(void);

void init_TXD(unsigned int);

void init_RXD(void);


//************************************************************

//---------------------主函数-------------------------------

//************************************************************

void main(void)

{

WDTCTL = WDTPW + WDTHOLD;

init_DCO();

init_TimerA();

_EINT();

while(1)

{

init_RXD();

LPM0;

if(verify_fault)

{

init_TXD(0xAA);

init_TXD(0xBB);

init_TXD(0xCC);

verify_fault=0;

}

else

{

RxDate = (RxDate & 0xff); //只取8位数据位

init_TXD(RxDate);

}

}

}



/*************************************************

函数(模块)名称:init_TimerA

功能:        初始化TA

输入参数: 无

输出参数: 无

函数返回值说明:无

使用的资源:

它说明: 无

*************************************************/

void init_TimerA(void)

{

TACTL |= TASSEL1+MC1+TACLR; //SMCLK ,连续记数,请TAR

CCTL0 |= OUT; //默认比较输出为1

P1DIR |= TXD;

P1SEL |= RXD+TXD;

}

/*************************************************

函数(模块)名称:init_TXD

功能:        初始化发送

输入参数: 无

输出参数: 无

函数返回值说明:无

使用的资源:

它说明: 无

*************************************************/

void init_TXD(unsigned int Byte)

{

Count_T = 11; //起始位,8位数据位,奇偶校验位,停止位

CCR0 = TAR + OneBit;

//-----------------------------------------------------

for(char i=0;i<8;i++)

{

if(Movebit & Byte)

{

ParityBit++;

}

Movebit <<= 1;

}

Movebit = 0x01;

if(ParityBit%2 == 0)

{

TxDate |=0x0200+Byte; //0010 xxxx xxxx

}

else

{

TxDate |=0x0300+Byte; //0011 xxxx xxxx

}

ParityBit = 0;

//--------------------------------------------------------


TxDate=TxDate<<1; //往左移1位,产生起始位


CCTL0 = OUTMOD0 + CCIE; //置位,比较中断允许

//while ( CCTL0 & CCIE ); //等待发送完毕

LPM0;


}

/*************************************************

函数(模块)名称:init_RXD

功能:        初始化接收

输入参数: 无

输出参数: 无

函数返回值说明:无

使用的资源:

它说明: 无

*************************************************/

void init_RXD(void)

{

Count_R=10; //8位数据+1位偶校验+停止位

//置位,中断允许,下降沿捕获,同步捕获,选择CCI0B作输入源

CCTL0 = OUTMOD0+CCIE+CM1+CAP+SCS+CCIS0;


}


/*************************************************

函数(模块)名称:TA中断函数

功能:        捕获,定时

输入参数: 无

输出参数: 无

函数返回值说明:无

使用的资源:

它说明: 无

*************************************************/


#pragma vector=TIMERA0_VECTOR

__interrupt void TimerA(void)

{

CCR0 += OneBit;

if(CCTL0 & CCIS0) //接收状态

{

if(CCTL0 & CAP) //处于捕获状态,开始接收数据

{

CCTL0 &= ~CAP; //转变比较方式

CCR0 += HalfBit; //再加半位的时间

}

else //正在接收数据

{

if(Count_R!=0) //8个数据,1个奇偶校验,1个停止位 没有接收完毕

{

RxDate=RxDate>>1;

if(CCTL0 & SCCI) //接收到的是1

{

RxDate |= 0x0200; //共接收10位

ParityBit ++;

}

if(Count_R==1) //接收到的最后一位是停止位

{

if( !(RxDate & 0x0200))//最后一位不是1(停止位出错)

{

verify_fault = 1;

}

}

Count_R--;

}

else //数据接收完毕

{

CCTL0 &= ~CCIE;

if( !(ParityBit&0x01) ) //9位数据里 1的个数是偶数(因为包括了停止位)

{

verify_fault = 1; //偶校验失败

}

ParityBit = 0;

LPM0_EXIT; //退出LPM3,CPU开始处理要发送的数据

} //数据接收完毕


}//正在接收数据

} //接收状态

else //处于发送状态

{

if(Count_T!=0) //8位数据+1位偶校验+停止位 没有发送完毕

{

if(TxDate & 0x0001) //发送的是1

{

CCTL0 &= ~OUTMOD2; //OUTMOD0是置位

}

else //发送的是0

{

CCTL0 |= OUTMOD2; //OUTMOD0+OUTMOD2是复位

}


TxDate=TxDate>>1;

Count_T--;

}

else //8位数据+1位偶校验+停止位 发送完毕

{

CCTL0 &= ~CCIE;

LPM0_EXIT;

}


}

}


/*************************************************

函数(模块)名称:init_DCO

功能:        初始化_DCO

输入参数: 无

输出参数: 无

函数返回值说明:无

使用的资源:

它说明: 设置XT2的各个参数

*************************************************/

void init_DCO(void)

{

SCFI0 |= FN_2;

SCFQCTL = 121; //(121+1)*32768=7.99MHz

FLL_CTL0 |= XCAP14PF;

FLL_CTL1 = 0;

}

可以参考下

使用特权

评论回复
| 2020-11-19 23:38 | 显示全部楼层
mark 真给力

使用特权

评论回复
| 2020-11-19 23:41 | 显示全部楼层
利用定时器的比较捕获功能来模拟串口是完全可以的

使用特权

评论回复
| 2020-11-19 23:45 | 显示全部楼层
看完楼主的模拟程序的,很是不错的啊,帮着顶起一下的啊

使用特权

评论回复
| 2020-11-19 23:49 | 显示全部楼层
两个定时器就可以模拟另外两路了。

使用特权

评论回复
| 2020-11-19 23:54 | 显示全部楼层
楼主可以试试ti的m3的产品,串口比较多的。

使用特权

评论回复
| 2020-11-19 23:57 | 显示全部楼层

模拟串口的可以通过定时器的模拟来实现的。

需要定时器的捕获功能的,还有时钟源的处理很重要的。

使用特权

评论回复
| 2020-11-26 09:47 | 显示全部楼层
本帖最后由 ayb_ice 于 2020-11-26 09:49 编辑

用外部中断,来个外部中断就按位时间将开始,停止,8个BIT接收一遍,符合要求就当接收了一个字节,简单可靠,中断优先级最高
缺点,占用时间

可以改进下,中断后,启动定时器,然后在定时器中断中接收,可以节省大量时间

使用特权

评论回复
| 2020-12-1 20:04 | 显示全部楼层
关于模拟串口的我原来做过的,那时只不过是用MSP430F249的单片机做的,效果还是不错的。

使用特权

评论回复
| 2020-12-1 20:09 | 显示全部楼层

你是要直接配置寄存器的呢
还是使用定时器模拟串口操作。

使用特权

评论回复
| 2020-12-1 20:13 | 显示全部楼层
你是要定时器模拟的?
还是串口模拟软件呢?

使用特权

评论回复
| 2020-12-1 20:17 | 显示全部楼层
IO口模拟UART串口?

使用特权

评论回复
| 2020-12-1 20:22 | 显示全部楼层
  IO 口模拟串口,是要根据时序来完成的

使用特权

评论回复
| 2020-12-1 20:26 | 显示全部楼层
串口的每位需延时0.104秒,中间可执行96个指令周期。

使用特权

评论回复
| 2020-12-1 20:29 | 显示全部楼层
用IO模拟SPI或者I2C都可以啊

使用特权

评论回复
| 2020-12-1 20:32 | 显示全部楼层
需要模拟出串口时序

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

关闭

热门推荐上一条 /5 下一条

在线客服 快速回复 返回顶部 返回列表