/* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
/* ERROR code and STATUS definitions */
#define ERROR_OK 1
#define ERROR_ERROR 0
#define START_CYCLE 1
#define WAIT_CYCLE 0
// 2007-3-13
/*Global variables*/
unsigned char SCIIniTx;
unsigned char SCIString[13]={0xF5,0xDD,0x03,0x00,0x23,0x04,0xFF,0xFF,0xFC,0x72,0x73,0xF5,0xa};
//unsigned char SCIString[12]={'B','C','D','E','F','G','H','I','J','K','L','\0'};
unsigned char *SCIStringp;
unsigned char Stringcase;
unsigned char * g_pSci1TxHead = SCIString;
unsigned char * g_pSci1TxBufEnd = SCIString + 11;
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 20 void SCI0_rx(void)
{
if (SCI0SR1 & 0x80)
{ /*If transmission flag is set*/
SCI0SR1;
//if(*(SCIStringp++) != '\0')
if (g_pSci1TxHead != g_pSci1TxBufEnd)
{
//if(*SCIStringp > 0xD)
//{ /*Avoid to change CR and LF characters*/
// SCI0DRL=*SCIStringp + Stringcase;
//}
//else{
g_pSci1TxHead++;
SCI0DRL= *SCIStringp++;;
//}
}
else
{
g_pSci1TxHead = SCIString;
SCIIniTx=START_CYCLE; /*Start new transmission cycle*/
SCI0CR2 &= 0x7F; /*Disable TDRE interrupt*/
}
}
if(SCI0SR1 & 0x20){ /*If reception flag is set*/
SCI0SR1;
if(SCI0DRL == 'U' || SCI0DRL == 'u'){
Stringcase = 0x00; /*Uppercase the character string*/
}
else if(SCI0DRL == 'L' || SCI0DRL == 'l'){
Stringcase = 0x20; /*Lowercase the character string*/
}
}
return;
}
#pragma CODE_SEG DEFAULT
//************************************************************************
// SCI参数设置
//************************************************************************
void Init_SCI(void)
{
//SCI0与Monitor通信
SCI0BDL=6;
SCI0BDH=0; //CLOCK=7.3728MHz, bps=38400
SCI0CR1=0x16; //9 bit, 偶效验
SCI0CR2=0x2C; //中止符产生器关闭
}
void SCITx(unsigned char SCIByte){
SCI0DRL = SCIByte; /*Write data byte to SCIDRL register*/
SCI0CR2 |= 0x80; /*Enable TDRE interrupt*/
}
void main(void)
{
/* put your own code here */
EnableInterrupts;
Init_SCI();
SCIIniTx = START_CYCLE; /*Initialize transmission cycle flag*/
for (;;)
{
if(SCIIniTx == START_CYCLE){
SCIIniTx = WAIT_CYCLE;
SCIStringp=SCIString; /*Set pointer to character string*/
SCITx(*SCIStringp + Stringcase);/*Send first byte of string*/
}
}
}
[此贴子已经被作者于2007-3-26 16:53:09编辑过]
作者: zhudongpo 时间: 2007-3-26 16:57
上面代码是通过改动 AN2883SW.ZIP 。
发送数据时大部分时间是正确的,中间会出现错误数据帧。
使用是mc9s12dp256b ,PC端使用 串口调试助手V2.2.exe 接收数据。
麻烦Strongchen 给看看。谢谢了
作者: strongchen 时间: 2007-3-26 17:26
这么一大段程序,还真不好办呢:))。要么你把整个PROJECT打包贴出来,我有空时试试吧。
作者: zhudongpo 时间: 2007-3-26 18:06
http://bbs.eccn.com/uploadImages/SCI.rar
作者: strongchen 时间: 2007-3-27 16:55
你的数据格式为什么要选9位而不是8位的?
作者: zhudongpo 时间: 2007-3-28 11:37
[upload=image/pjpeg]uploadImages/SCI.JPG[/upload]
作者: zhudongpo 时间: 2007-3-28 11:54
SCI0CR1=0x12; 9bit
SCI0CR1=0x02; 8bit 串口助手接收的数据根本就是错的。。
数据格式为什么要选9位而不是8位的?是因为 使用了偶校验
我试过多种组合了,还是有问题,请问strongchen 如果串口助手的设置如上图所示,
SCI0CR1 应该怎么设置呢,还是除了SCI0CR1 之外别的控制寄存器也需要进行设置,
急切等待您的答复,谢谢。
[此贴子已经被作者于2007-3-28 11:54:41编辑过]
作者: zhudongpo 时间: 2007-3-30 10:02
我试过将波特率降低为9600,还是有问题。
请问各位有什么方法吗,谢谢了。
作者: strongchen 时间: 2007-3-30 10:05
有没有用示波器看过波形?数据和脉冲宽度是否正确?
作者: strongchen 时间: 2007-3-30 15:03
数据长度并不包括校验位。
作者: strongchen 时间: 2007-3-30 15:34
我把程序稍微改了一下,你试试看(主要是对TDRE的操作)。
interrupt 20 void SCI0_rx(void)
{
if (SCI0SR1 & 0x80)
{ /*If transmission flag is set*/
SCI0SR1;
//if(*(SCIStringp++) != '\0')
if (g_pSci1TxHead != g_pSci1TxBufEnd)
{
//if(*SCIStringp > 0xD)
//{ /*Avoid to change CR and LF characters*/
// SCI0DRL=*SCIStringp + Stringcase;
//}
//else{
g_pSci1TxHead++;
SCI0DRL= *SCIStringp++;;
//}
}
else
{
g_pSci1TxHead = SCIString;
SCIIniTx=START_CYCLE; /*Start new transmission cycle*/
/*SCI0CR2 &= 0x7F; /*Disable TDRE interrupt*/
}
}
if(SCI0SR1 & 0x20){ /*If reception flag is set*/
SCI0SR1;
if(SCI0DRL == 'U' || SCI0DRL == 'u'){
Stringcase = 0x00; /*Uppercase the character string*/
}
else if(SCI0DRL == 'L' || SCI0DRL == 'l'){
Stringcase = 0x20; /*Lowercase the character string*/
}
}
return;
}
#pragma CODE_SEG DEFAULT
//************************************************************************
// SCI²ÎÊýÉèÖÃ
//************************************************************************
void Init_SCI(void)
{
//SCI0ÓëMonitorͨÐÅ
////SCI0BDL=6;
SCI0BDL=13;
SCI0BDH=0; //CLOCK=7.3728MHz, bps=38400
////SCI0CR1=0x16; //9 bit, żЧÑé
SCI0CR1=0x06; //8 bit, żЧÑé
SCI0CR2=0x2C; //ÖÐÖ¹·û²úÉúÆ÷¹Ø±Õ
SCI0CR2 |= 0x80; /*Enable TDRE interrupt*/
}
void SCITx(unsigned char SCIByte){
SCI0DRL = SCIByte; /*Write data byte to SCIDRL register*/
/*SCI0CR2 |= 0x80; /*Enable TDRE interrupt*/
}
void main(void)
{
/*
DDRB = 1;
while (1){
PORTB_BIT0^=1;
}*/
/* put your own code here */
EnableInterrupts;
Init_SCI();
SCIIniTx = START_CYCLE; /*Initialize transmission cycle flag*/
for (;;)
{
if(SCIIniTx == START_CYCLE){
SCIIniTx = WAIT_CYCLE;
SCIStringp=SCIString; /*Set pointer to character string*/
SCITx(*SCIStringp + Stringcase);/*Send first byte of string*/
}
}
}
[此贴子已经被strongchen于2007-3-30 15:34:02编辑过]
作者: zhudongpo 时间: 2007-3-31 14:36
strongchen 你好,你说数据长度并不包括校验位,SCI0CR1=0x06; //8 bit,
我已经试过了,收到数据是错误的,而SCI0CR1=0x16; //9 bit 收到数据才是正确的,
只是不停的发送过程中,我通过串口助手看到有一些错误的数据而已。用8bit 收到数据全错了。
作者: zhudongpo 时间: 2007-3-31 14:39
[upload=image/pjpeg]uploadImages/SCI0.JPG[/upload]
作者: zhudongpo 时间: 2007-3-31 14:43
SCI0CR1_M=0 ,我使用了偶校验,按照上图给的信息,BIT7 位应该是校验位吧,那数据位
不就只有7位了吗,而串口助手中数据位是8位呀,你认为能接收到正确的数据???
作者: strongchen 时间: 2007-4-2 09:41
你是对的,在SCI的Datasheet中,数据长度应该包括校验位。 但是在某些通讯软件中,数据长度的定义可能有所不同。如在HyperTerminal中,它的数据长度就没有9位的选项。
[此贴子已经被strongchen于2007-4-2 9:41:04编辑过]
作者: strongchen 时间: 2007-4-2 11:06
附件在你的程序基础上略作修改。用HyperTerminal通讯效果很好,没有错码出现。注意我用的是16M的外部时钟,8M的总线频率;8位数据长度,无校验位。你可以试试。
http://bbs.eccn.com/uploadImages/Temp.rar
作者: strongchen 时间: 2007-4-2 11:08
这是HyperTermian通讯的截图。注意每次“A”都发了2次,这应该是你程序的问题。
[upload=image/pjpeg]uploadImages/New Picture.jpg[/upload]
作者: zhudongpo 时间: 2007-4-2 11:47
通讯软件中数据长度最大的确只有8,现在我的数据长度也是8位呀,虽然设置时9位,
但是校验位占了一位呀,数据位还是8位。所以在通讯软件中设置8位数据位应该没有
错误吧。关键是通讯软件接收的数据,开始可是正确的,经过一段时间就有错误数据
出现,SCI的设置项应该没有问题,那问题出在哪里呢? 您能给一个中断方式发送一段
数据的例程吗?我用的是 AN2883SW.ZIP 测试没有通过,您给修改了一下,经过测试
还是没有解决问题。还有什么地方需要注意,才能彻底解决出现的问题呢。
作者: strongchen 时间: 2007-4-2 12:11
我这边试下来并没有问题。看起来你的硬件可能有问题,也可能是晶振频率或信号不稳定。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) |
Powered by Discuz! 7.0.0 |