标题:
STC15W408AS单片机串口通讯带串口移植功能+ADC采集+定时器+EEPROM综合程序
[打印本页]
作者:
zhangxinchun
时间:
2023-7-11 13:07
标题:
STC15W408AS单片机串口通讯带串口移植功能+ADC采集+定时器+EEPROM综合程序
【声明】此程序仅用于学习与参考!
*********************************************************************/
#include<STC15W408AS.h>
#include<math.h> //计算小数点的头文件
#include <intrins.h> //用nop函数延时的头文件
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int //宏定义无符号整型
/*数据类型定义*/
typedef signed char int8;
typedef signed int int16;
typedef signed long int32;
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
#define S1_S0 0x40 //P_SW3.6
#define S1_S1 0x80 //P_SW3.7
#define ENABLE_IAP 0x83 //系统工作时钟<12MHz 时,对IAP_CONTR 寄存器设置此值
#define CMD_IDLE 0
#define CMD_READ 1
#define CMD_PROGRAM 2
#define CMD_ERASE 3
#define ENABLE_IAP 0x83//SYSCLK<12MH
#define IAP_ADDRESS 0x0000 //存储地址
#define FOSC 11059200L
#define BAUD 9600
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540个时钟
#define ADC_SPEEDL 0x20 //360个时钟
#define ADC_SPEEDH 0x40 //180个时钟
#define ADC_SPEEDHH 0x60 //90个时钟
uint AD_H=0,AD_L=0,AD_Dat=0;
/*定义遥控引脚*/
sbit IN1 = P1^2; /*下*/
sbit IN2 = P1^3; /*上*/
sbit IN3 = P1^4; /*西*/
sbit IN4 = P1^5; /*东*/
sbit IN5 = P1^6; /*北*/
sbit IN6 = P1^7; /*南*/
sbit IN7 = P5^4; /*2*/
sbit IN8 = P5^5; /*1*/
/*AD采集引脚*/
sbit ADC1=P1^1;//电池电压检测
/*供电自锁引脚*/
sbit gong_dian=P1^0;//电池电压检测
/*指示灯引脚*/
sbit RUN=P3^2;//运行指示灯
sbit dian_chi=P3^3;//电池指示灯
/*控制引脚*/
sbit MD0=P3^4;//工作模式
sbit MD1=P3^5;//工作模式
uchar DATE=0x00;//遥控器按键
uchar add=0X01; //遥控器地址
bit write=0;
bit flag_zx=0;
uchar sendBuf[10]; //发送缓冲区
uchar receBuf[10]; //接收缓冲区
uchar r=0;//串口接收数据计数值
uint tcnt=0;//定时器时间计数值
uchar sec=0;//定时器时间计数值
uchar k=100;//延时函数时间函数
bit bz1=0;//输入按键标志
bit bz2=0;//输入按键标志
bit bz3=0;//输入按键标志
bit bz4=0;//输入按键标志
bit bz5=0;//输入按键标志
bit bz6=0;//输入按键标志
bit bz7=0;//输入按键标志
bit bz8=0;//输入按键标志
bit dian_liang_bj=0;//电量报警
bit fa_she_bj=0;//数据发射标志
uchar adc1=0;//AD采集的数据值
/********************************************************************
定义 ISP/IAP/EEPROM 命令
*********************************************************************/
void IapIdle();//禁用 ISP/IAP/EEPROM functionmake 单片机 在 一 安全 状态
uint8 IapReadByte(uint16 addr);//读数据
void IapProgramByte(uint16 addr, uint8 dat);//写数据
void IapEraseSector(uint16 addr);//擦除数据
void KEY1();//模式1函数
void delay(uchar t);//擦除数据
void clear_receBuf();//清空发送缓冲区
void send_date1();//数据函数
void senduart1();//发送函数
void InitADC();//AD转换初始化程序
uchar ADCRead(uchar px); //转换输出的数据 (PX为通道口)
/********************************************************************
AD转换初始化程序
*********************************************************************/
void InitADC()//AD转换初始化程序
{
P1ASF = 0x02; //设置P1.1口AD转换,必须加// P1M0=0X1E;
ADC_RES = 0; //AD数据寄存器清空
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;//打开AD电源,转换周期210
_nop_(); //延时一个机器周期
_nop_();
_nop_(); //延时一个机器周期
}
/********************************************************************
AD转换控制程序
*********************************************************************/
uchar ADCRead(uchar px) //转换输出的数据 (PX为通道口)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL |px| ADC_START;//开始转换
_nop_(); //延时一个机器周期
_nop_(); //延时一个机器周期
_nop_(); //延时一个机器周期
_nop_(); //延时一个机器周期
while (!(ADC_CONTR & ADC_FLAG));//等待转换结束
ADC_CONTR &= ~ADC_FLAG; //关闭AD转换
// AD_H = ADC_RES; // 修改的 注:把高8位AD值付给AD_H
// AD_H <<= 2; // 修改的 注:高八位左移2位
// AD_L = ADC_RESL & 0x03; // 修改的 注:取低两位
// AD_Dat = AD_H | AD_L; // 修改的 注:把高八位和低两位合并在一起
// AD_Dat = AD_H | AD_L; // 修改的 注:把高八位和低两位合并在一起
AD_Dat = ADC_RES;
return AD_Dat; //返回数据
}
/********************************************************************
延时函数
*********************************************************************/
void delay(uchar t)
{
uchar i,j;
for(i=0;i<t;i++)
{
for(j=130;j>0;j--);
{ ;
}
}
}
/****************数据函数*********************/
void send_date1()//数据函数
{
adc1=ADCRead(1);
sendBuf[0]=0xAA;
sendBuf[1]=add;
sendBuf[2]=adc1;
sendBuf[3]=DATE;
sendBuf[4]=0xBB;
}
/****************发送函数*********************/
void senduart1()//发送函数
{
SBUF=sendBuf[0];while(!TI);TI=0;
SBUF=sendBuf[1];while(!TI);TI=0;
SBUF=sendBuf[2];while(!TI);TI=0;
SBUF=sendBuf[3];while(!TI);TI=0;
SBUF=sendBuf[4];while(!TI);TI=0;
}
/********************************************************************
模式1函数
*********************************************************************/
void KEY1()
{
//if(gong_dian==0){gong_dian=0;}
if((IN1==0)&&(bz1==0)){delay(k);if((IN1==0)&&(bz1==0)){fa_she_bj=1;DATE=0x01;send_date1();senduart1();bz1=1;}}if((IN1==1)&&(bz1==1)){delay(k);if((IN1==1)&&(bz1==1)){bz1=0;fa_she_bj=0;}}//输入按键
if((IN2==0)&&(bz2==0)){delay(k);if((IN2==0)&&(bz2==0)){fa_she_bj=1;DATE=0x02;send_date1();senduart1();bz2=1;}}if((IN2==1)&&(bz2==1)){delay(k);if((IN2==1)&&(bz2==1)){bz2=0;fa_she_bj=0;}}//输入按键
if((IN3==0)&&(bz3==0)){delay(k);if((IN3==0)&&(bz3==0)){fa_she_bj=1;DATE=0x03;send_date1();senduart1();bz3=1;}}if((IN3==1)&&(bz3==1)){delay(k);if((IN3==1)&&(bz3==1)){bz3=0;fa_she_bj=0;}}//输入按键
if((IN4==0)&&(bz4==0)){delay(k);if((IN4==0)&&(bz4==0)){fa_she_bj=1;DATE=0x04;send_date1();senduart1();bz4=1;}}if((IN4==1)&&(bz4==1)){delay(k);if((IN4==1)&&(bz4==1)){bz4=0;fa_she_bj=0;}}//输入按键
if((IN5==0)&&(bz5==0)){delay(k);if((IN5==0)&&(bz5==0)){fa_she_bj=1;DATE=0x05;send_date1();senduart1();bz5=1;}}if((IN5==1)&&(bz5==1)){delay(k);if((IN5==1)&&(bz5==1)){bz5=0;fa_she_bj=0;}}//输入按键
if((IN6==0)&&(bz6==0)){delay(k);if((IN6==0)&&(bz6==0)){fa_she_bj=1;DATE=0x06;send_date1();senduart1();bz6=1;}}if((IN6==1)&&(bz6==1)){delay(k);if((IN6==1)&&(bz6==1)){bz6=0;fa_she_bj=0;}}//输入按键
if((IN7==0)&&(bz7==0)){delay(k);if((IN7==0)&&(bz7==0)){fa_she_bj=1;DATE=0x07;send_date1();senduart1();bz7=1;}}if((IN7==1)&&(bz7==1)){delay(k);if((IN7==1)&&(bz7==1)){bz7=0;fa_she_bj=0;}}//输入按键
if((IN8==0)&&(bz8==0)){delay(k);if((IN8==0)&&(bz8==0)){fa_she_bj=1;DATE=0x08;send_date1();senduart1();bz8=1;}}if((IN8==1)&&(bz8==1)){delay(k);if((IN8==1)&&(bz8==1)){bz8=0;fa_she_bj=0;}}//输入按键
//if((IN1==0)||(IN2==0)||(IN3==0)||(IN4==0)||(IN5==0)||(IN6==0)||(IN7==0)||(IN8==0)){RUN=0;}
if(dian_liang_bj==0)
{
if((IN1==1)&&(IN2==1)&&(IN3==1)&&(IN4==1)&&(IN5==1)&&(IN6==1)&&(IN7==1)&&(IN8==1)){RUN=0;}//电量正常时绿灯亮
}
else{RUN=1;dian_chi;sec=0;}//当电池电量低时,红灯亮
}
/********************************************************************
定时中断服务函数
*********************************************************************/
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
tcnt++; //每过250ust tcnt 加一
if(tcnt==400) //计满400 次(1/10 秒)时
{
tcnt=0; //重新再计
sec++;
if(dian_liang_bj==0){if(fa_she_bj==1){if(sec>=1){RUN=!RUN;sec=0;}}}
if(dian_liang_bj==1){if(sec>=20){dian_chi=!dian_chi;sec=0;}}
//if(sec==10){RUN=!RUN;sec=0;}
//if(sec>=20){dian_chi=!dian_chi;sec=0;}
}
}
/*****************清空发送缓冲区*************************/
void clear_receBuf()
{
uchar i;
for(i=0;i<5;i++)
{
receBuf[i]=0;
}
}
/********************************************************************
主函数
*********************************************************************/
void main()
{
P1M0 = 0x00; P1M1 = 0x02; //IO定义
P3M0 = 0x00; P3M1 = 0x00; //IO定义
SCON = 0x50;
T2L = (65536 - (FOSC/4/BAUD));
T2H = (65536 - (FOSC/4/BAUD))>>8;
AUXR = 0x14;
AUXR |= 0x01;
ES = 1;
EA = 1;
add= IapReadByte(0x01);//读取存储的值
if(add>=100){add=1;}
//sj2= IapReadByte(0x02);//读取存储的值
TMOD=0x02; //定时器工作在方式2
TH0=0x06; //对TH0 TL0 赋值
TL0=0x06;
TR0=1; //开始定时
ET0=1;
EA=1;
/*串口移植*/
ACC = P_SW1;
ACC &= ~(S1_S0 | S1_S1); //S1_S0=1 S1_S1=0
ACC |= S1_S0; //(P3.6/RxD_2, P3.7/TxD_2)
P_SW1 = ACC;
InitADC();//AD转换初始化程序
sec=0;
MD0 = 0;//工作模式
MD1 = 0;//工作模式
gong_dian=0;
while(1)
{
KEY1();//按键函数
if(write==1) //修改板子地址
{
write=0;
add=1;
IapEraseSector(0); //擦除扇区
IapProgramByte(0x01,add);//写入新的地址
//IapProgramByte(0x02,sj2);//写入新的地址
}
}
}
/********************************************************************
串口中断函数
*********************************************************************/
void Uart() interrupt 4 using 1
{
if (RI)
{
RI=0; //接收标志清零
receBuf[r++&0x0F]=SBUF; //把接受的数据存储到BUT数组中
if(receBuf[0]!=0xaa){r=0;}
if(r>=5)
{ r=0;
flag_zx=1;
}
}
if(flag_zx==1)
{
flag_zx=0;
if((receBuf[0]==0xaa)&&(receBuf[1]==0x00)&&(receBuf[2]==0x00)&&(receBuf[3]==0x00)&&(receBuf[4]==0xbb))
{
write=1;
sendBuf[0]=0xaa;
sendBuf[1]=add;
sendBuf[2]=0x00;
sendBuf[3]=0x00;
sendBuf[4]=0xbb;
senduart1();
}
if((receBuf[0]==0xaa)&&(receBuf[1]==0xff)&&(receBuf[2]==0xff)&&(receBuf[3]==0xff)&&(receBuf[4]==0xbb))
{
sendBuf[0]=0xaa;
sendBuf[1]=add;
sendBuf[2]=0xff;
sendBuf[3]=0xff;
sendBuf[4]=0xbb;
senduart1();
}
clear_receBuf();
}
}
/********************************************************************
结束
*********************************************************************/
void IapIdle(){//禁用 ISP/IAP/EEPROM functionmake 单片机 在 一 安全 状态
IAP_CONTR = 0; //
IAP_CMD = 0; //
IAP_TRIG = 0; //
IAP_ADDRH = 0x80; //
IAP_ADDRL = 0; //
}
uint8 IapReadByte(uint16 addr){//读数据
uint8 dat;
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_READ;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
dat = IAP_DATA;
IapIdle();
return dat;
}
void IapProgramByte(uint16 addr, uint8 dat){//写数据
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_PROGRAM;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_DATA = dat;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
IapIdle();
}
void IapEraseSector(uint16 addr){//擦除数据
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_ERASE;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
IapIdle();
}
/********************************************************************
结束
*********************************************************************/
复制代码
STC15W408AS 串口 ADC 定时器 EEPROM.rar
2023-7-11 13:07 上传
点击文件名下载附件
57.87 KB, 下载次数: 121
Keil代码
作者:
jovew
时间:
2023-7-12 07:35
好东西! 只是还没有看明白。学习之。
作者:
13869300
时间:
2023-10-28 19:42
好东西,正在学习下载看看
作者:
STC新未来
时间:
2023-10-30 09:53
感谢楼主的精彩分享,非常的权威!后续若需要更多的案例可参考ISP软件上的范例程序
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1