📄 sp2349.c
字号:
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!申 明!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
// //
//本驱动程序属于成都视普科技公司所有,仅允许免费用于本公司销售的产品中,未 //
//经书面许可任何单位或个人不可将本程序用于其它用途,否则将追究其法律责任 //
// //
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/***************************************************************************
SP2339_SP2349_driver.c source file SP2339/SP2349 serial communication
example for MCS-51 MCU
Author: Wen hua, 2004-05-26
***************************************************************************/
/********************************上位机资源占用*****************************
****** RAM:14(BYTE,不包含子串口发送缓冲)+5(BIT),ROM:270BYTE(内核部分) *****
****** 接收一个字节耗用15条指令(MAX),发送一个字节耗用45条指令(MAX) *****
***************************************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
bit bdata uart_busy; //上位机串口发送状态标志,"1"表示上位机串口"忙"(正发送数据
//到子串口,新数据只需送入子串口发送缓冲区即可,"0"表示上位
//机串口"空闲",需用户程序将"TI=1"来启动子串口数据发送
bit bdata instruction_flag; //上位机发送指令请求标志,上位机需要发送指令时必须
//先将待发发送指令放到"instruction_buf",之后将该
//标志设置为"1"即可.标志变为"0"后可继续发送指令
bit bdata uart0_r_flag,uart1_r_flag,uart2_r_flag;
//上位机接收到子串口数据
//标志,"1"表示上位机接收到相应子串口数据,主程序可通过查询
//该标志的方式判断相应子串口是否接收到新数据(主程序取走刚
//收到的新数据后,必须将该标志清"0",以便识别下一个新数据)
uchar idata uart0_t_buf[8]; //子串口0数据发送缓冲区(大小可由用户随意配置)
uchar idata uart1_t_buf[8]; //子串口1数据发送缓冲区(大小可由用户随意配置)
uchar idata uart2_t_buf[16]; //子串口2数据发送缓冲区(大小可由用户随意配置)
uchar idata uart0_r_buf,uart1_r_buf,uart2_r_buf;
//上位机接收子串口数据缓
//冲存储器,上位机通过判断"uart0_r_flag"等标志
//是否为"1",来决定是否读取该寄存器的数据
uchar idata uart_pointer; //子串口发送数据指针,中断服务程序通过该指针轮询
//发送数据到各子串口,保证各子串口的数据不丢失
uchar idata instruction_buf; //指令缓冲(用户可将设置SP2339/SP2349的指令放入
//该寄存器,由驱动程序自动完成指令发送)
uchar idata uart0_t_byte_num,uart1_t_byte_num,uart2_t_byte_num;
//等待发送到各
//子串口的字节数,"0"表示相应子串口发送缓冲区"空"
//主程序可以通过判断该标志是否为"0"来决定是否向
//相应子串口发送后续数据
uchar idata uart0_coef,uart1_coef,uart2_coef;
//子串口分频系数/波特率控制寄存
//器,具体用法请参见设置子串口的波特率指令部分
uchar idata uart0_coef_buf,uart1_coef_buf,uart2_coef_buf;
//分频系数缓冲寄存器
uint idata x=5000,y=5000,z=5000;
//-----------------------定义寻址的基址----------------------------------------
uchar base_AdrL=0x00;
uchar base_AdrH=0x80; //片选地址
sbit write=P3^6;
sbit read=P3^7;
//-----------------------定义地址指针,指向基址--------------------------------
uchar xdata SRAM_base_Adr = base_Adr;
//-----------------------------------------------------------------------------
// 函数名称:SRAM_write
// 入口参数:SRAM_ADR,setting
// 出口参数:无
// 函数功能:写外部数据存储区
//-----------------------------------------------------------------------------
void SRAM_write(uchar SRAM_ADR, uchar setting)
{
ALE=1;
P1=base_AdrL;
p2=base_AdrH;
ALE=0;
write=0;
p1 = setting;
write=1;
}
//-----------------------------------------------------------------------------
// 函数名称:SRAM_read
// 入口参数:SRAM_ADR
// 出口参数:SRAM_data
// 函数功能:读外部数据存储区
//-----------------------------------------------------------------------------
uchar SRAM_read(uchar SRAM_ADR)
{
uchar SRAM_data;
ALE=1;
P1=base_AdrL;
p2=base_AdrH;
ALE=0;
read=0;
SRAM_data = *( SRAM_base_Adr + SRAM_ADR );
read=1;
return(SRAM_data);
}
/*****************************************************************************
功能:设定SP2339/SP2349输入、输出地址,可根据实际电路修改
*****************************************************************************/
sbit AdrIn0 =P1^0; /* 连接到SP2339/SP2349的PIN0(ADRO0)*/
sbit AdrIn1 =P1^1; /* 连接到SP2339/SP2349的PIN1(ADRO1)*/
sbit AdrOut0=P1^2; /* 连接到SP2339/SP2349的PIN18(ADRI0)*/
sbit AdrOut1=P1^3; /* 连接到SP2339/SP2349的PIN17(ADRI1)*/
#define _DEBUG_SUB_MODULE
/****************************************************************************
功能:上位机串口中断服务函数,自动完成子串口数据发送(自动发送数据包)和数据接收
(单字节接收并缓存)以及自动发送上位机配置指令等
输入:uart0_coef,uart1_coef,uart2_coef,uart0_t_byte_num,uart1_t_byte_num,
uart2_t_byte_num,uart0_t_buf[???],uart1_t_buf[???],uart2_t_buf[???],
instruction_flag,instruction_buf,uart_busy
输出:uart0_r_flag,uart0_r_flag,uart1_r_flag,uart1_r_buf,uart2_r_buf,uart2_r_buf
uart_busy
*****************************************************************************/
serial () interrupt 4 {
if(RI){
RI=0;
if(AdrIn1){ //子串口2接收到一个字节
uart2_r_buf=SBUF; //缓存子串口2收到的数据,以便接收后续数据
uart2_r_flag=1; //置子串口2收到数据标志,便于主程序查询
}
else if(AdrIn0){ //子串口1接收到一个字节
uart1_r_buf=SBUF; //缓存子串口1收到的数据,以便接收后续数据
uart1_r_flag=1; //置子串口1收到数据标志,便于主程序查询
}
else { //子串口0接收到一个字节
uart0_r_buf=SBUF; //缓存子串口0收到的数据,以便接收后续数据
uart0_r_flag=1; //置子串口0收到数据标志,便于主程序查询
}
}
else{
TI=0;
switch(uart_pointer){
case 0:{
uart_pointer++;
if((--uart0_coef_buf)==0){
uart0_coef_buf=uart0_coef;
if(uart0_t_byte_num){
AdrOut0=0;
AdrOut1=0;
SBUF=uart0_t_buf[--uart0_t_byte_num];
break;
}
else if(uart1_t_byte_num|uart2_t_byte_num){
goto t_nop_instruction;
}
else if(instruction_flag){
goto t_nop_instruction;
}
else {uart_busy=0;break;}
}
else{goto t_nop_instruction;}
}
case 1:{
uart_pointer++;
if((--uart1_coef_buf)==0){
uart1_coef_buf=uart1_coef;
if(uart1_t_byte_num){
AdrOut0=1;
AdrOut1=0;
SBUF=uart1_t_buf[--uart1_t_byte_num];
break;
}
else if(uart0_t_byte_num|uart2_t_byte_num){
goto t_nop_instruction;
}
else if(instruction_flag){
goto t_nop_instruction;
}
else {uart_busy=0;break;}
}
else{goto t_nop_instruction;}
}
case 2:{
uart_pointer++;
if((--uart2_coef_buf)==0){
uart2_coef_buf=uart2_coef;
if(uart2_t_byte_num){
AdrOut0=0;
AdrOut1=1;
SBUF=uart2_t_buf[--uart2_t_byte_num];
break;
}
else if(uart0_t_byte_num|uart1_t_byte_num){
goto t_nop_instruction;
}
else if(instruction_flag){
goto t_nop_instruction;
}
else {uart_busy=0;break;}
}
else{goto t_nop_instruction;}
}
case 3:{
uart_pointer=0;
t_nop_instruction: //标号:发送指令标志为“1”的清零
AdrOut0=1;
AdrOut1=1;
if(instruction_flag){
instruction_flag=0;
SBUF=instruction_buf;
break;
}
else {SBUF=0;break;}
}
}
}
}
/*****************************************************************************
功能:上位机发送指令到SP2339/SP2349,该函数主要完成将命令字放入指令缓冲区,并置
相应标志即可,指令发送将由中断服务函数自动完成
输入:欲操作的命令字
输出:无
*****************************************************************************/
void instruction_set (uchar instruction_word){ //入口参数:操作SP23X9的命令字
while(instruction_flag); //等待操作SP23X9的其它命令结束
instruction_buf=instruction_word; //加载命令字
instruction_flag=1; //置发送命令请求标志
if(uart_busy==0){TI=1;uart_busy=1;} //判断中断服务程序中的发送部分
} //是否处于激活状态,否则将主动激活上位机中断服务程序数据发送部分,执行数据发送
/*****************************************************************************
功能:初始化上位机串口波特率为38400BPS(采用TIMER 2)
输入:无
输出:无
*****************************************************************************/
void init_serialcomm(void){
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
T2CON |= 0x34; //TMOD: timer 2, mode 2, 16-bit reload,timer 2 run
RCAP2H = 0xFF; //Baud:38400 fosc=11.0592MHz
RCAP2L = 0xF7; //Baud:38400 fosc=11.0592MHz
// RCAP2H = 0xFF; //Baud:19200 fosc=11.0592MHz
// RCAP2L = 0xEE; //Baud:19200 fosc=11.0592MHz
// RCAP2H = 0xFF; //Baud:38400 fosc=22.1184MHz
// RCAP2L = 0xEE; //Baud:38400 fosc=22.1184MHz
// RCAP2H = 0xFF; //Baud:76800 fosc=22.1184MHz
// RCAP2L = 0xF7; //Baud:76800 fosc=22.1184MHz
IE |= 0x90; //Enable Serial Interrupt
IP = 0x10; //只允许串口中断为最高优先级,其它为次优先级。
uart0_t_byte_num=0; //初始化串口0发送缓冲区"空"
uart1_t_byte_num=0; //初始化串口1发送缓冲区"空"
uart2_t_byte_num=0; //初始化串口2发送缓冲区"空"
}
#ifdef _DEBUG_SUB_MODULE
/*****************************************************************************
功能:SP2339/SP2349上电后默认3个子串口分频系数都为"1",所以初始化相应子串口系数
为"1",子串口发送数据计数器清"0",用户可根据具体情况设置或删除。
输入:无
输出:无
*****************************************************************************/
/**/
void set_sub_serialcomm(void){
uart0_coef=0x01; //
uart1_coef=0x01; //
uart2_coef=0x01; //
uart0_coef_buf=0x01; //
uart1_coef_buf=0x01; //
uart2_coef_buf=0x01; //
}
main(){
init_serialcomm();
set_sub_serialcomm();
while(1){
/*
instruction_set(0x07); //初始化SP23X9为11BIT数据格式
instruction_set(0x1A); //设置子串口0的波特率为4800BPS@8.0MHz
uart0_coef=0x02; //置子串口0的分频系数为"2"
uart0_coef_buf=uart0_coef; //同上,初始化子串口0
instruction_set(0x20); //设置子串口1的波特率为2400BPS@8.0MHz
uart1_coef=0x04; //置子串口1的分频系数为"4"
uart1_coef_buf=uart1_coef; //同上,初始化子串口1
instruction_set(0x26); //设置子串口2的波特率为2400BPS@8.0MHz
uart2_coef=0x08; //置子串口2的分频系数为"8"
uart2_coef_buf=uart2_coef; //同上,初始化子串口2
*/
if(uart0_t_byte_num==0){
uchar i=0;
uart0_t_buf[i++]=0x30;
uart0_t_buf[i++]=0x31;
uart0_t_buf[i++]=0x32;
uart0_t_buf[i++]=0x33;
uart0_t_buf[i++]=0x34;
uart0_t_buf[i++]=0x35;
uart0_t_buf[i++]=0x36;
uart0_t_buf[i++]=0x37;
uart0_t_byte_num=i;
if(uart_busy==0){
TI=1;
uart_busy=1;
}
if(x==5000){ //子串口0按照9600BPS发送2K*8=16KBYTE
instruction_set(0x19);
uart0_coef=0x01;
uart0_coef_buf=uart0_coef;
}
else if(x==3000){ //子串口0按照4800BPS发送1K*8=8KBYTE
instruction_set(0x1A);
uart0_coef=0x02;
uart0_coef_buf=uart0_coef;
}
else if(x==2000){ //子串口0按照2400BPS发送0.5K*8=4KBYTE
instruction_set(0x1B);
uart0_coef=0x04;
uart0_coef_buf=uart0_coef;
}
else if(x==1500){ //子串口0按照1200BPS发送0.25K*8=2KBYTE
instruction_set(0x1C);
uart0_coef=0x08;
uart0_coef_buf=uart0_coef;
}
else if(x==1250){ //子串口0按照600BPS发送0.125K*8=1KBYTE
instruction_set(0x1D);
uart0_coef=0x10;
uart0_coef_buf=uart0_coef;
}
else if(x==1125){
instruction_set(0x19);
uart0_coef=0x01;
uart0_coef_buf=uart0_coef;
x=5000;
}
x--;
}
if(uart1_t_byte_num==0){
uchar i=0;
uart1_t_buf[i++]=0x40;
uart1_t_buf[i++]=0x41;
uart1_t_buf[i++]=0x42;
uart1_t_buf[i++]=0x43;
uart1_t_buf[i++]=0x44;
uart1_t_buf[i++]=0x45;
uart1_t_byte_num=i;
if(uart_busy==0){
TI=1;
uart_busy=1;
}
if(y==5000){ //子串口1按照9600BPS发送2K*6=12KBYTE
instruction_set(0x1E);
uart1_coef=0x01;
uart1_coef_buf=uart1_coef;
}
else if(y==3000){ //子串口1按照4800BPS发送1K*6=6KBYTE
instruction_set(0x1F);
uart1_coef=0x02;
uart1_coef_buf=uart1_coef;
}
else if(y==2000){ //子串口1按照2400BPS发送0.5K*6=3KBYTE
instruction_set(0x20);
uart1_coef=0x04;
uart1_coef_buf=uart1_coef;
}
else if(y==1500){ //子串口1按照1200BPS发送0.25K*6=1.5KBYTE
instruction_set(0x21);
uart1_coef=0x08;
uart1_coef_buf=uart1_coef;
}
else if(y==1250){ //子串口1按照600BPS发送0.125K*6=0.75KBYTE
instruction_set(0x22);
uart1_coef=0x10;
uart1_coef_buf=uart1_coef;
}
else if(y==1125){
instruction_set(0x1E);
uart1_coef=0x01;
uart1_coef_buf=uart1_coef;
y=5000;
}
y--;
}
if(uart2_t_byte_num==0){
uchar i=0;
uart2_t_buf[i++]=0x50;
uart2_t_buf[i++]=0x51;
uart2_t_buf[i++]=0x52;
uart2_t_buf[i++]=0x53;
uart2_t_buf[i++]=0x54;
uart2_t_buf[i++]=0x55;
uart2_t_buf[i++]=0x56;
uart2_t_buf[i++]=0x57;
uart2_t_byte_num=i;
if(uart_busy==0){
TI=1;
uart_busy=1;
}
if(z==5000){ //子串口2按照9600BPS发送2K*8=16KBYTE
instruction_set(0x23);
uart2_coef=0x01;
uart2_coef_buf=uart2_coef;
}
else if(z==3000){ //子串口2按照4800BPS发送1K*8=8KBYTE
instruction_set(0x24);
uart2_coef=0x02;
uart2_coef_buf=uart2_coef;
}
else if(z==2000){ //子串口2按照2400BPS发送0.5K*8=4KBYTE
instruction_set(0x25);
uart2_coef=0x04;
uart2_coef_buf=uart2_coef;
}
else if(z==1500){ //子串口2按照1200BPS发送0.25K*8=2KBYTE
instruction_set(0x26);
uart2_coef=0x08;
uart2_coef_buf=uart2_coef;
}
else if(z==1250){ //子串口2按照600BPS发送0.125K*8=1KBYTE
instruction_set(0x27);
uart2_coef=0x10;
uart2_coef_buf=uart2_coef;
}
else if(z==1125){
instruction_set(0x23);
uart2_coef=0x01;
uart2_coef_buf=uart2_coef;
z=5000;
}
z--;
}
}
}
#endif // _DEBUG_SUB_MODULE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -