初始化程序如下:
void Vk3214_Init(void){
uchar i;
FREEDOG;
VK3214_RST=1;
delay(10);
VK3214_RST=0;
delay(10);
VK3214_RST=1;
delay(10);
write_reg(1,SCTLR,0x38); //串口1波特率設置為9600,使能串口1
write_reg(2,SCTLR,0x38);//串口2ㄌ羋噬柚夢?600,使能串口1
//write_reg(3,SCTLR,0x30);//禁止串口3
//write_reg(4,SCTLR,0x30);//禁止串口4
//write_reg(0,SCONR,0x00);
//write_reg(1,SCONR,0x00);
//write_reg(2,SCONR,0x00);
//write_reg(3,SCONR,0x00);
//write_reg(0,SFWCR,0x00);
//write_reg(1,SFWCR,0x00);
//write_reg(2,SFWCR,0x00);
//write_reg(3,SFWCR,0x00);
write_reg(1,SFOCR,0xcf);//接收FIFO觸點控制1BYTE
//i = read_reg(1, SFOCR);
//SENDCOM1(&i,1);
write_reg(2,SFOCR,0xcf);
//write_reg(2,SFOCR,0xcc);
write_reg(1,SIER,0x01);//使能接收FIFO觸點中斷,禁止發(fā)送FIFO觸點中斷
write_reg(2,SIER,0x01);
//write_reg(2,SIER,0x00);
//write_reg(3,SIER,0x00);
//write_reg(0,SIFR,0x00);
//write_reg(1,SIFR,0x00);
//write_reg(2,SIFR,0x00);
//write_reg(3,SIFR,0x00);
write_reg(1,GIR,0X30);//使能串口1, 2中斷
while(read_reg(1,SFSR))//讀完串口1,2接收FIFO中的數(shù)據(jù)
read_reg(1,SFDR);
while(read_reg(2,SFSR))
read_reg(2,SFDR);
write_reg(1,GUCR,0X10);//主串口波特率設為38400
AUXR=0x14;///S2使用獨立波特率發(fā)生器,S2波特率不加倍BRTX12設為1
BRT=0xf7;//0xee;//0xf7;//設置波特率38400
delay(10);
}
為保證及時接收到擴展串口的數(shù)據(jù),接收FIFO觸發(fā)點中斷設置為1,即接收到1個字節(jié)就產(chǎn)生中斷,發(fā)送因為是單片機控制,不用設置觸發(fā)點中斷。
void uart_sendByte(unsigned char dat)
{
S2BUF=dat;
while(!(S2CON & 0x02)); //waite for data to transmit completely
S2CON &= 0xFD;
}
//通過串口發(fā)送1個字節(jié)的數(shù)據(jù),dat為發(fā)送的數(shù)據(jù)
unsigned char uart_recByte(void)
{
unsigned char rec=0;
while(!(S2CON & 0x01)); //waite to recieve data in SBUF0
rec=S2BUF;
S2CON &= 0xFE;
return rec;
}
//接收一個字節(jié)的數(shù)據(jù),函數(shù)返回讀取到的數(shù)據(jù)
unsigned char read_reg(unsigned char port,unsigned char reg)
{
uchar i;
EX1 = 0; //此處關外部1中斷,避免在讀寫寄存器時,串口芯片接收到數(shù)據(jù)引起外部中斷,在外部中斷調(diào)用相同的寄存器會導致死機
uart_sendByte(((port-1)《《4)+reg);
i = uart_recByte();
EX1 = 1;
return i;
}
//讀取寄存器的值,port為子串口的路數(shù),reg為寄存器的地址,返回值是寄存器的值
void write_reg(unsigned char port,unsigned char reg,unsigned char dat)
{
EX1 = 0;
uart_sendByte(0x80+((port-1)《《4)+reg);
uart_sendByte(dat);
EX1 = 1;
}
從上面的函數(shù)可以看出,單片機的串口控制VK3214的串口,讀寫都是先發(fā)送VK3214的寄存器地址,然后再讀寫數(shù)據(jù),所以如果單片機的串口和擴展的子串口的波特率設置成一樣,會導致子串口接收FIFO溢出,再考慮到用單片機的一個串口控制2-4個子串口,所以單片機的串口波特率一定要是子串口波特率的倍數(shù),我現(xiàn)在擴展2個串口,子串口的波特率為9600,所以我把單片機串口的波特率設置為38400,是子串口的4倍。倍數(shù)要考慮好,太慢會導致接收FIFO溢出,太快會導致發(fā)送FIFO的數(shù)據(jù)還沒發(fā)出去,有送進來新的數(shù)據(jù),發(fā)送FIFO溢出。
VK3214復位后根據(jù)外接的晶振,主,子串口都有默認的波特率,單片機上電后先把波特率設為和VK3214主串口波特率一樣,初始化VK3214完成后,在改變VK3214的主串口波特率和單片機串口的波特率。見初始化程序的最后部分。
接下來關鍵的部分是外部中斷程序的處理。程序如下:
void Int1Init(void) interrupt 2
{
uchar x,i,j,z;
EX1 = 0;
uart_sendByte(GIR);
i=uart_recByte();
FREEDOG;
if(i&0x01)
{
uart_sendByte((0《《4)+SSR);
z=uart_recByte();
z&=0x01;
while(z==0)
{
uart_sendByte((0《《4)+SFDR);
com2rev[com2revidx++] = uart_recByte();
FREEDOG;
if(com2revidx》=COM2_MAX)com2revidx=0;
uart_sendByte((0《《4)+SSR);
z=uart_recByte();
z&=0x01;
}
}
if(i&0x02)
{
uart_sendByte((1《《4)+SSR);
z=uart_recByte();
z&=0x01;
while(z==0)
{
uart_sendByte((1《《4)+SFDR);
com3rev[com3revidx++] = uart_recByte();
FREEDOG;
if(com3revidx》=COM3_MAX)com3revidx=0;
uart_sendByte((1《《4)+SSR);
z=uart_recByte();
z&=0x01;
}
}
EX1 = 1;
}
進入中斷后先判斷是哪個子串口產(chǎn)生的中斷,如果是子串口1產(chǎn)生的接收中斷,那么讀子串口1的寄存器SSR,看接收FIFO是否為空,不為空就一直讀子串口1的接收FIFO,直到FIFO為空。中斷程序中一定要把接收FIFO的數(shù)據(jù)讀完,因為我設置的接收FIFO觸發(fā)點數(shù)據(jù)為1。如果不讀完退出中斷,IRQ仍然會為低,還會繼續(xù)進入中斷程序。讀完后,IRQ才變?yōu)楦摺?/p>
評論
查看更多