一个经PL2303转换的串口调试实例

2020-02-08 09:13发布

用一块淘宝上淘来的空PCB焊接上PIC18F46J11和PL2303,经过调试,让MCU可以给主机发ASCII码串,MCU可以接收主机键盘发出的字符。

硬件电路如下2图。
BACK.jpg (643.26 KB, 下载次数: 0) 下载附件 2012-4-19 15:11 上传

调试中MCU与PL2303之间的串口比较难调,把背板图中连接二者的跳线去掉,让各自的TX/RX短路,形成自环。PC侧可以让自己键盘输入都在自己的屏幕上显示;MCU侧可以运行中断后在串口接收缓冲区看到自己发送的数据。

调试正常的程序如下。其中RTCC部分可以为后续的开发(例如连续输出日期时间)保留。

#include "P18f46j11.h"
#include "usart.h"
#include "delays.h"

#define LED1 LATDbits.LATD2

void main (void);
void InterruptHandlerHigh (void);
unsigned int test1;
unsigned char Rtimehi[4]={0x0,0x03,0x05,0x10},Rtimelo[4]={0x12,0x09,0x0,0x30};
unsigned char usart_data[20];                //usart送来的数据暂存
unsigned char *usart_head;                //usart数据暂存区的头指针
unsigned char try_tx1;

//***************主函数*****************
void main()
{
unsigned char i,j;
//*************************RTCC初始化*******************
T1GCON=0;
T1CON=0X3F;    //允许tmr1的振荡器
RTCCFG=0X05;
PADCFG1=0X02;   //输出秒时钟
ALRMRPT=0XFF;   //闹钟重复次数
ALRMCFG=0XC4;   //闹钟开,定闹开,指针指向分秒,1“掩码
ALRMVALL=0;    //秒内容清除
ALRMVALH=0;    //分内容清除
PIE3bits.RTCCIE=1;  //开闹钟中断
//以下汇编部分为实时钟写入开启前的必需动作
EECON2=0x55;                        //修改重定位锁定标志前的必须序列
EECON2=0xAA;
RTCCFGbits.RTCWREN=1;        //开启写入
RTCCFGbits.RTCEN=1;
RTCCFG|=0x03;  //置指针为0b11
while (RTCCFGbits.RTCSYNC); //等待不忙
for (i=0;i<4;i++) //写
{
RTCVALL=Rtimelo;
RTCVALH=Rtimehi;
}
//以下汇编部分为关闭实时钟写入前的必需动作
EECON2=0x55;                        //修改重定位锁定标志前的必须序列
EECON2=0xAA;
RTCCFGbits.RTCWREN=0;        //关闭写入
RTCCFG|=0x03;  //置指针为0b11
while (RTCCFGbits.RTCSYNC); //等待不忙
for (i=0;i<4;i++) //读
{
Rtimelo=RTCVALL;
Rtimehi=RTCVALH;
}
//***************USART1 INIT**********************
Close1USART();                                                //关闭串口
//下句打开串口1,收中断,高速,4800
Open1USART( USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_LOW,
103 );
RCSTA1bits.ADDEN=0;                                        //消除9位通信的地址相关设置
BAUDCON1bits.ABDOVF=0;                                //将波特率计满指示清0
BAUDCON1bits.RXDTP=0;                                //将空闲反相关闭
BAUDCON1bits.BRG16=1;                                //选择16位波特率
usart_head=usart_data;        //指针到队列头

//****************INTERRUPT INIT*******************
INTCONbits.PEIE=1;
INTCONbits.GIE=1;

//**************************IO INIT********************
TRISDbits.TRISD2=0;                //RD2 led output
test1=0;
try_tx1=0x30;

//**************************主循环************************
while(1)
{
Delay1KTCYx(100);                                        //减慢发送速度而设
//以下读RTCC到两个数组中
RTCCFG|=0x03;  //置指针为0b11
while (RTCCFGbits.RTCSYNC); //等待不忙
for (i=0;i<4;i++) //读
{
Rtimelo=RTCVALL;
Rtimehi=RTCVALH;
}

//检查串口空则循环发送ASCII表中的部分码
if (TXSTA1bits.TRMT)
{
TXREG1=try_tx1;
LED1^=1;                                                        //测试指示
if (try_tx1>0x76)
try_tx1=0x30;
else
try_tx1++;
}

//到达MAIN最后部分
}
}
//----------------------------------------------------------------------------
// High priority interrupt vector
#pragma code InterruptVectorHigh = 0x08
void
InterruptVectorHigh (void)
{
  _asm
    goto InterruptHandlerHigh   //jump to interrupt routine
  _endasm
}
//----------------------------------------------------------------------------
// High priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh ()
{
if (PIR1bits.RC1IF)
{
*usart_head = RCREG1;                //若USART1收中断,以读出数据方式清除标志
usart_head++;                                //指针增1,指向下个地址
if (usart_head>=&usart_data[19])                //若到队尾
usart_head=usart_data;        //指针回到队列头
}
else if (PIR3bits.RTCCIF)
{
PIR3bits.RTCCIF = 0;         //clear interrupt flag
test1++;
}
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
sicom
1楼-- · 2020-02-09 07:50
PC与mcu平台上实现自己需要内容的显示和会话, 很有实际意义。
在工作中碰到不少这类课题。

一周热门 更多>