|
发表于 2023-5-29 16:29:45
|
显示全部楼层
鉴于很多网友没有足够的积分下载,我试试直接把代码贴到这里,这个是我测试通过的,用stc15F104E读取电量信息,电压信息等。主要还是要知道芯片的一些寄存器地址才能操作。
- /*---------------------------------------------------------------------*/
- /* --- STC MCU Limited ------------------------------------------------*/
- /* --- STC15Fxx 系列 软件模拟串口举例----------------------------------*/
- /* --- Mobile: (86)13922805190 ----------------------------------------*/
- /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
- /* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/
- /* --- Web: www.STCMCU.com --------------------------------------------*/
- /* --- Web: www.GXWMCU.com --------------------------------------------*/
- /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
- /* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序 */
- /*---------------------------------------------------------------------*/
- //本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
- //若无特别说明,工作频率一般为11.0592MHz
- #include "reg51.h"
- #include <intrins.h> //包含_nop_()函数定义的头文件
- #include<stdio.h>
- #include "math.h"
- #include<string.h>
- //-----------------------------------------
- //define baudrate const
- //BAUD = 65536 - FOSC/3/BAUDRATE/M (1T:M=1; 12T:M=12)
- //NOTE: (FOSC/3/BAUDRATE) must be greater then 98, (RECOMMEND GREATER THEN 110)
- //#define BAUD 0xF400 // 1200bps [url=home.php?mod=space&uid=3057940]@[/url] 11.0592MHz
- //#define BAUD 0xFA00 // 2400bps @ 11.0592MHz
- //#define BAUD 0xFD00 // 4800bps @ 11.0592MHz
- #define BAUD 0xFE80 // 9600bps @ 11.0592MHz
- //#define BAUD 0xFF40 //19200bps @ 11.0592MHz
- //#define BAUD 0xFFA0 //38400bps @ 11.0592MHz
- //#define BAUD 0xEC00 // 1200bps @ 18.432MHz
- //#define BAUD 0xF600 // 2400bps @ 18.432MHz
- //#define BAUD 0xFB00 // 4800bps @ 18.432MHz
- //#define BAUD 0xFD80 // 9600bps @ 18.432MHz
- //#define BAUD 0xFEC0 //19200bps @ 18.432MHz
- //#define BAUD 0xFF60 //38400bps @ 18.432MHz
- //#define BAUD 0xE800 // 1200bps @ 22.1184MHz
- //#define BAUD 0xF400 // 2400bps @ 22.1184MHz
- //#define BAUD 0xFA00 // 4800bps @ 22.1184MHz
- //#define BAUD 0xFD00 // 9600bps @ 22.1184MHz
- //#define BAUD 0xFE80 //19200bps @ 22.1184MHz
- //#define BAUD 0xFF40 //38400bps @ 22.1184MHz
- //#define BAUD 0xFF80 //57600bps @ 22.1184MHz
- sfr AUXR = 0x8E;
- sbit RXB = P3^0; //define UART TX/RX port
- sbit TXB = P3^1;
- typedef bit BOOL;
- typedef unsigned char BYTE;
- typedef unsigned int WORD;
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- #define MAX_SIZE 32 //定义缓存空间
- BYTE TBUF,RBUF;
- BYTE TDAT,RDAT;
- BYTE TCNT,RCNT;
- BYTE TBIT,RBIT;
- BOOL TING,RING;
- BOOL TEND,REND;
- void UART_INIT();
- void putchar0(BYTE dat);
- uchar SMbus_GetCrc8(uchar previous,uchar dat);
- uchar PEC_cal(uchar pec[],uchar n);
- void Delay30us();
- void Delay200us();
- void Delay15us();
- void AT24C04_Start();
- void AT24C04_Stop();
- void AT24C04_SendACK(bit ack);
- bit AT24C04_RecvACK();
- void AT24C04_SendByte(uchar dat);
- uchar AT24C04_RecvByte();
- bit AT24C04_ReadPage(uchar adress,bit IsBlock);
- void AT24C04_WritePage(uchar address,uchar dat[],uchar len);
- BYTE t, r;
- sbit SDA=P3^2; //数据接口
- sbit SCL=P3^3; //时钟接口
- uchar Receive_Buffer[MAX_SIZE]=0; //接收数据缓冲区
- uchar Buf_Index;
- uchar BUF[MAX_SIZE]={0}; //数据缓存区 idata
- uchar a_SM_PecTable[16]={0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D};
- /***********************************************
- 函数名称: SMbus_GetCrc8
- 函数功能: 计算CRC的值
- 输入参数: previous,上一个数据的CRC值,用于多个数据的CRC运算,
- 单个CRC运算无作用,值要设成0
- 输出参数: CRC8
- 备 注:
- ***********************************************/
- uchar SMbus_GetCrc8(uchar previous, uchar dat)
- {
- uchar crc=0;
- crc = 0;
- dat = previous ^ dat;
- crc = (crc << 4) ^ a_SM_PecTable[((crc ^ dat) >> 4) & 0x0F];
- dat <<= 4;//准备下一个位域,域宽4
- crc = (crc << 4) ^ a_SM_PecTable[((crc ^ dat) >> 4) & 0x0F];
- return crc;
- }
- uchar PEC_cal(uchar pec[],uchar n)
- {
- uchar crc=0;
- uchar i;
- for(i=0;i<n;i++)
- {
- crc = SMbus_GetCrc8(crc,pec[i]);
- }
- return crc;
- }
- /**************************************
- 向AT24C04写1页(16字节)数据
- 将TESTDATA开始的16个测试数据写如设备的00~0F地址中
- **************************************/
- void AT24C04_WritePage(uchar address,uchar dat[],uchar len)
- {
- uchar i,pec[MAX_SIZE];
- pec[0]=0x16;;
- pec[1]=address;
- AT24C04_Start(); //起始信号
- AT24C04_Stop(); //停止信号
- AT24C04_Start();
- AT24C04_SendByte(0x16); //发送设备地址+写信号
- AT24C04_SendByte(address); //发送存储单元地址
- for (i=0; i<len; i++)
- {
- AT24C04_SendByte(dat[i]);
- pec[i+2]=dat[i];
- }
- AT24C04_SendByte(PEC_cal(pec,len+2));
- AT24C04_Stop(); //停止信号
- }
- /**************************************
- 从电池中读取指定地址的数据到BUF中
- **************************************/
- bit AT24C04_ReadPage(uchar adress,bit IsBlock)
- {
- uchar i,pec[MAX_SIZE],Pecreg,k;
- uchar Num;
- pec[0]=0x16;
- pec[1]=adress;
- pec[2]=0x17;
- for (k=0; k<3; k++)
- {
- AT24C04_Start(); //起始信号
- AT24C04_Stop(); //停止信号
- AT24C04_Start();
- AT24C04_SendByte(0x16); //发送设备地址+写信号
- AT24C04_SendByte(adress); //发送存储单元地址
- AT24C04_Start(); //起始信号
- AT24C04_SendByte(0x17); //发送设备地址+读信号
- BUF[0] = AT24C04_RecvByte();
- AT24C04_SendACK(0); //回应ACK
- if(IsBlock)
- {
- Num=BUF[0]+1;
- }
- else
- {
- Num=2;
- }
- pec[3]=BUF[0];
- for (i=1; i<Num+1; i++)
- {
- BUF[i] = AT24C04_RecvByte();
- pec[i+3]=BUF[i];
- if (i == Num)
- {
- AT24C04_SendACK(1); //最后一个数据需要会NAK
- }
- else
- {
- AT24C04_SendACK(0); //回应ACK
- }
- }
- AT24C04_Stop(); //停止信号
- Pecreg=PEC_cal(pec,Num+3);
- if(Pecreg==BUF[Num])
- {
- return 1;
- break;
- }
- Delay30us();
- }
- return 0;
- }
- /**************************************
- 延时5微秒(STC12C5A60S2@12M)
- 不同的工作环境,需要调整此函数
- 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
- 实际延时有8us
- n=20 30us 10khz
- **************************************/
- void Delay30us() //@11.0592MHz stc15F104E
- {
- unsigned char i;
- i = 80;
- while (--i);
- }
- void Delay15us() //@11.0592MHz
- {
- unsigned char i;
- _nop_();
- _nop_();
- i = 38;
- while (--i);
- }
- void Delay200us() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 3;
- j = 34;
- do
- {
- while (--j);
- } while (--i);
- }
- /**************************************
- 起始信号
- **************************************/
- void AT24C04_Start()
- {
- Delay30us();//
- SDA = 1; //拉高数据线
- Delay30us();
- SCL = 1; //拉高时钟线
- Delay30us(); //延时
- SDA = 0; //产生下降沿
- Delay30us(); //延时
- SCL = 0; //拉低时钟线
- Delay30us(); //
- }
- /**************************************
- 停止信号
- **************************************/
- void AT24C04_Stop()
- {
- Delay30us();//
- SCL = 0;
- Delay30us();
- SDA = 0; //拉低数据线
- Delay30us();
- SCL = 1; //拉高时钟线
- Delay30us(); //延时
- SDA = 1; //产生上升沿
- Delay30us(); //延时
- }
- /**************************************
- 发送应答信号
- 入口参数:ack (0:ACK 1:NAK)
- **************************************/
- void AT24C04_SendACK(bit ack)
- {
- SDA = ack; //写应答信号
- Delay30us();
- SCL = 1; //拉高时钟线
- Delay30us(); //延时
- SCL = 0; //拉低时钟线
- Delay30us(); //延时
- }
- /**************************************
- 接收应答信号
- **************************************/
- bit AT24C04_RecvACK()
- {
- bit Y;
- Delay30us();
- SDA = 1;
- Delay30us();
- SCL = 0;
- Delay30us();
- SCL = 1; //拉高时钟线
- Delay30us(); //延时
- Y = SDA; //读应答信号
- Delay30us(); //
- SCL = 0; //拉低时钟线
- Delay30us(); //延时
- return Y;
- }
- /**************************************
- 向IIC总线发送一个字节数据
- **************************************/
- void AT24C04_SendByte(uchar dat)
- {
- uchar i;
- Delay15us();
- for (i=0; i<8; i++) //8位计数器
- {
- if((dat<<i)&0x80)
- SDA = 1;
- else //移出数据的最高位
- SDA = 0; //送数据口
- Delay15us();
- SCL = 1; //拉高时钟线
- Delay30us(); //延时
- SCL = 0; //拉低时钟线
- Delay15us(); //延时
- }
- i=0;
- Delay200us();//block一定要延时200us才能正确返回
- while((AT24C04_RecvACK()==1)&&(i<250))
- {
- i++;
- Delay15us();
- }
- }
- /**************************************
- 从IIC总线接收一个字节数据
- **************************************/
- uchar AT24C04_RecvByte()
- {
- uchar i;
- uchar dat = 0;
- SDA = 1; //使能内部上拉,准备读取数据
- Delay15us();
- for (i=0; i<8; i++) //8位计数器
- {
- dat <<= 1;
- SCL = 1; //拉高时钟线
- Delay15us(); //延时
- dat |= SDA; //读数据
- Delay15us(); //
- SCL = 0; //拉低时钟线
- Delay30us(); //延时
- }
- return dat;
- }
- //
- void Check()
- {
- uchar i;
- uchar buffer[MAX_SIZE];
- switch(Receive_Buffer[0])
- {
- case 0x72:// 'r'查询状态
- {
- switch(Receive_Buffer[1])
- {
- case 0x21:
- case 0x20:
- case 0x22:
- case 0x23:
- case 0x2F:
- {
- if(AT24C04_ReadPage(Receive_Buffer[1],1))
- {
- for(i=0;i<BUF[0]+2;i++)
- {
- putchar0(BUF[i]);
- }
- }else
- putchar0(0xee);
- }
- break;
- default:
- {
- if(AT24C04_ReadPage(Receive_Buffer[1],0))
- {
- for(i=0;i<3;i++)
- {
- putchar0(BUF[i]);
- }
- }else
- putchar0(0xee);
- }
- break;
- }
- }
- break;
- case 0x73:
- {
- switch(Receive_Buffer[1])
- {
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x3C:
- case 0x3D:
- case 0x3E:
- case 0x3F:
- {
- memcpy(buffer,&Receive_Buffer[3],Receive_Buffer[2]);
- AT24C04_WritePage(Receive_Buffer[1],buffer,Receive_Buffer[2]);
- break;
- }
- default :
- {
- putchar0(0xee);
- break;
- }
- }
- }
- break;
- default :
- break;
- }
- }
- //
- void putchar0(BYTE dat)
- {
- while (!TEND);
- TEND = 0;
- TBUF = dat;
- TING = 1;
-
- }
- /****************************************************************************
- 函数功能:uart0发送字符串数据
- 入口参数:*s
- 出口参数:
- ****************************************************************************/
- void puts0(char *s)
- {
- while (*s)
- {
- putchar0(*s);
- s++;
- }
- }
- //
- void main()
- {
- TMOD = 0x00; //timer0 in 16-bit auto reload mode
- AUXR = 0x80; //timer0 working at 1T mode
- TL0 = BAUD;
- TH0 = BAUD>>8; //initial timer0 and set reload value
- TR0 = 1; //tiemr0 start running
- ET0 = 1; //enable timer0 interrupt
- PT0 = 1; //improve timer0 interrupt priority
- EA = 1; //open global interrupt switch
- UART_INIT();
- while (1)
- { //user's function
- if (REND)
- {
- REND = 0;
- //BUF[r++ & 0x0f] = RBUF;
- if(RBUF == 0x68)//0x68 作为帧头
- {
- Buf_Index = 0;
- }else {
- Receive_Buffer[Buf_Index++ & 0x0f] = RBUF;
- }
- if((Receive_Buffer[0]==0x72)&&(Buf_Index==2))
- {
- Check();//
- }
- if((Receive_Buffer[0]==0x73)&&(Buf_Index==Receive_Buffer[2]+3))
- {
- Check(); //
- }
- }
- }
- }
- //-----------------------------------------
- //Timer interrupt routine for UART
- void tm0() interrupt 1
- {
- if (RING)
- {
- if (--RCNT == 0)
- {
- RCNT = 3; //reset send baudrate counter
- if (--RBIT == 0)
- {
- RBUF = RDAT; //save the data to RBUF
- RING = 0; //stop receive
- REND = 1; //set receive completed flag
- }
- else
- {
- RDAT >>= 1;
- if (RXB) RDAT |= 0x80; //shift RX data to RX buffer
- }
- }
- }
- else if (!RXB)
- {
- RING = 1; //set start receive flag
- RCNT = 4; //initial receive baudrate counter
- RBIT = 9; //initial receive bit number (8 data bits + 1 stop bit)
- }
- if (--TCNT == 0)
- {
- TCNT = 3; //reset send baudrate counter
- if (TING) //judge whether sending
- {
- if (TBIT == 0)
- {
- TXB = 0; //send start bit
- TDAT = TBUF; //load data from TBUF to TDAT
- TBIT = 9; //initial send bit number (8 data bits + 1 stop bit)
- }
- else
- {
- TDAT >>= 1; //shift data to CY
- if (--TBIT == 0)
- {
- TXB = 1;
- TING = 0; //stop send
- TEND = 1; //set send completed flag
- }
- else
- {
- TXB = CY; //write CY to TX port
- }
- }
- }
- }
- }
- //-----------------------------------------
- //initial UART module variable
- void UART_INIT()
- {
- TING = 0;
- RING = 0;
- TEND = 1;
- REND = 0;
- TCNT = 0;
- RCNT = 0;
- }
复制代码 |
|