用一块淘宝上淘来的空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++;
}
}
在工作中碰到不少这类课题。
一周热门 更多>