考号
prj
new
startup
scr
Driver
Seg.c
Seg.h
User
魔法棒
Output
头文件路径
Led
Led.c
#include "Led.h"
idata unsigned char temp_1=0x00;
idata unsigned char temp_1_Old=0xff;
//ucLed是且只能是0,1
void Led_Disp(unsigned char* ucLed)
{
unsigned char temp;
temp_1=0x00;
temp_1=(ucLed[0]<<0)|(ucLed[1]<<1)|
(ucLed[2]<<2)|(ucLed[3]<<3)|
(ucLed[4]<<4)|(ucLed[5]<<5)|
(ucLed[6]<<6)|(ucLed[7]<<7);
if(temp_1!=temp_1_Old)
{
P0=~temp_1;
temp=P2&0x1f;
temp=temp|0x80;
P2=temp;
temp=P2&0x1f;
P2=temp;
temp_1_Old=temp_1;
}
}
void Led_Off()
{
unsigned char temp;
P0=0xff;
temp=P2&0x1f;
temp=temp|0x80;
P2=temp;
temp=P2&0x1f;
P2=temp;
temp_1_Old=0x00;//关掉后我们需要将Old变成关闭
}
idata unsigned char temp_2=0x00;
idata unsigned char temp_2_Old=0xff;
void Beep(bit enable)
{
unsigned char temp;
if(enable)
temp_2|=0x40;
else
temp_2&=(~0x40);
if(temp_2!=temp_2_Old)
{
P0=temp_2;
temp=P2&0x1f;
temp=temp|0xa0;
P2=temp;
temp=P2&0x1f;
P2=temp;
temp_2_Old=temp_2;
}
}
void Motor(bit enable)
{
unsigned char temp;
if(enable)
temp_2|=0x20;
else
temp_2&=(~0x20);
if(temp_2!=temp_2_Old)
{
P0=temp_2;
temp=P2&0x1f;
temp=temp|0xa0;
P2=temp;
temp=P2&0x1f;
P2=temp;
temp_2_Old=temp_2;
}
}
void Relay(bit enable)
{
unsigned char temp;
if(enable)
temp_2|=0x10;
else
temp_2&=(~0x10);
if(temp_2!=temp_2_Old)
{
P0=temp_2;
temp=P2&0x1f;
temp=temp|0xa0;
P2=temp;
temp=P2&0x1f;
P2=temp;
temp_2_Old=temp_2;
}
}
Led.h
#include <STC15F2K60S2.H>
void Relay(bit enable);
void Motor(bit enable);
void Beep(bit enable);
void Led_Off();
void Led_Disp(unsigned char* ucLed);
测试main.c
#include <STC15F2K60S2.H>
#include "Led.h"
pdata unsigned char ucLed[8]={1,0,1,0,1,0,1,0};//全给1和temp_1_Old撞了
void main()
{
Led_Disp(ucLed);
Beep(1);
Motor(1);
Relay(1);
while(1)
{
}
}
Debug测试,小鹅通31
检测MCU选项
12Mhz
魔法棒Debug,Use,对应COM
配置,烧录,断电重连,开始仿真
Init
Init.c
#include "Init.h"
void System_Init()
{
unsigned char temp;
P0=0xff;
temp=P2&0x1f;
temp=temp|0x80;
P2=temp;
temp=P2&0x1f;
P2=temp;
P0=0x00;
temp=P2&0x1f;
temp=temp|0xa0;
P2=temp;
temp=P2&0x1f;
P2=temp;
}
Init.h
#include <STC15F2K60S2.H>
void System_Init();
Seg
Seg.c
#include "Seg.h"
pdata unsigned char Seg_Dula[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
void Seg_Disp(unsigned char Wela,unsigned char Dula,bit Point)
{
unsigned char temp;
P0=0x00;
temp=P2&0x1f;
temp=temp|0xe0;
P2=temp;
temp=P2&0x1f;
P2=temp;
P0=0x01<<Wela;
temp=P2&0x1f;
temp=temp|0xc0;
P2=temp;
temp=P2&0x1f;
P2=temp;
P0=Seg_Dula[Dula];
if(Point)
P0&=0x7f;
temp=P2&0x1f;
temp=temp|0xe0;
P2=temp;
temp=P2&0x1f;
P2=temp;
}
Seg.h
#include <STC15F2K60S2.H>
void Seg_Disp(unsigned char Wela,unsigned char Dula,bit Point);
测试main.c
#include <STC15F2K60S2.H>
#include "Seg.h"
pdata unsigned char Seg_Buf[8]={10,10,10,10,10,10,10,10};
idata unsigned char Seg_Pos=0;
idata unsigned char Seg_Slow_Down;
void main()
{
System_Init();
Seg_Disp(5,2,1);//第六个即第五位显示2,有小数点
while(1)
{
}
}
ISR
勾选使能定时器中断(定时器1)
void Timer1_Isr(void) interrupt 3
{
}
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
}
中断和测试main.c,顺手补齐Key,Seg,Led_Proc
#include <STC15F2K60S2.H>
#include "Led.h"
#include "Init.h"
#include "Seg.h"
pdata unsigned char ucLed[8]={0,0,0,0,0,0,0,0};
pdata unsigned char Seg_Buf[8]={10,10,10,10,10,10,10,10};
idata unsigned char Seg_Pos=0;
idata unsigned char Seg_Slow_Down;
void Key_Proc()
{
}
void Seg_Proc()
{
if(Seg_Slow_Down<20)return;
Seg_Slow_Down=0;
Seg_Buf[0]=1;
Seg_Buf[1]=2;
Seg_Buf[2]=3+',';
Seg_Buf[3]=4;
Seg_Buf[4]=5+',';
Seg_Buf[5]=6;
Seg_Buf[6]=7;
Seg_Buf[7]=8;
}
void Led_Proc()
{
ucLed[0]=1;
ucLed[1]=0;
ucLed[2]=1;
ucLed[3]=0;
ucLed[4]=1;
ucLed[5]=0;
ucLed[6]=1;
ucLed[7]=0;
Led_Disp(ucLed);
}
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
EA = 1;
}
void Timer1_Isr(void) interrupt 3
{
Seg_Slow_Down++;
Seg_Pos=(++Seg_Pos)%8;
//底层没有20的下标(超出上限),加一个',',显示小数点
if(Seg_Buf[Seg_Pos]>20)
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]-',',1);
else
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],0);
}
void main()
{
Timer1_Init();
System_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
关键点
//底层没有20的下标(超出上限),加一个',',显示小数点
if(Seg_Buf[Seg_Pos]>20)
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]-',',1);
else
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],0);
Timer1_Init();
Key(很重要)
Key.c
#include "Key.h"
unsigned char Key_Read()
{
unsigned char temp=0;
//独立按键
/*
if(P33==0)temp=4;
if(P32==0)temp=5;
if(P31==0)temp=6;
if(P30==0)temp=7;
*/
//矩阵键盘
//测量频率必须注释P34的所有相关
P44=1;P42=1;P35=1;//P34=1;
if(P30==0)return 0;//判断是否为串口触发
P44=0;P42=1;P35=1;//P34=1;
if(P33==0)temp=4;
if(P32==0)temp=5;
if(P31==0)temp=6;
if(P30==0)temp=7;
P44=1;P42=1;P35=1;//P34=1;
if(P30==0)return 0;
P44=1;P42=0;P35=1;//P34=1;
if(P33==0)temp=8;
if(P32==0)temp=9;
if((P33==0)&&(P32==0))return 89;
if(P31==0)temp=10;
if(P30==0)temp=11;
P44=1;P42=1;P35=1;//P34=1;
if(P30==0)return 0;
P44=1;P42=1;P35=0;//P34=1;
if(P33==0)temp=12;
if(P32==0)temp=13;
if(P31==0)temp=14;
if(P30==0)temp=15;
//频率注释
/*
P44=1;P42=1;P35=1;//P34=1;
if(P30==0)return 0;
P44=1;P42=1;P35=1;P34=0;
if(P33==0)temp=16;
if(P32==0)temp=17;
if(P31==0)temp=18;
if(P30==0)temp=19;
*/
P44=1;P42=1;P35=1;//P34=1;
P3=P3|0xef;//不影响频率,让P3变为双向口接受
return temp;
}
关键点
//测量频率必须注释P34的所有相关
P44=1;P42=1;P35=1;//P34=1;
if(P30==0)return 0;//判断是否为串口触发
//频率注释
/*
P44=1;P42=1;P35=1;//P34=1;
if(P30==0)return 0;
P44=1;P42=1;P35=1;P34=0;
if(P33==0)temp=16;
if(P32==0)temp=17;
if(P31==0)temp=18;
if(P30==0)temp=19;
*/
P44=1;P42=1;P35=1;//P34=1;
P3=P3|0xef;//不影响频率,让P3变为双向口接受
Key.h
#include <STC15F2K60S2.H>
unsigned char Key_Read();
双键
if((P33==0)&&(P32==0))return 89;
main.c测试
Debug检测数据
#include <STC15F2K60S2.H>
#include "Key.h"
idata unsigned char Key_Val,Key_Old,Key_Down,Key_Up;
idata unsigned char Key_Slow_Down;
idata unsigned char Key_Down_Data,Key_Up_Data;
void Key_Proc()
{
if(Key_Slow_Down<10)return;
Key_Slow_Down=0;
Key_Val=Key_Read();
Key_Down=Key_Val&(Key_Val^Key_Old);
Key_Up=~Key_Val&(Key_Val^Key_Old);
Key_Old=Key_Val;
if(Key_Down!=0)
Key_Down_Data=Key_Down;
if(Key_Up!=0)
Key_Up_Data=Key_Up;
}
void Timer1_Isr(void) interrupt 3
{
Key_Slow_Down++;
}
void main()
{
Timer1_Init();
System_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
ds1302
ds1302.c
/* # DS1302代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "ds1302.h"
#include "intrins.h"
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^3;
//
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
//写入11:12:13 -> 0x11 0x12 0x13
void Set_Rtc(unsigned char* ucRtc)
{
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);//关闭写保护
Write_Ds1302_Byte(0x80,0x80);//关闭CH,停止计时
for (i=0;i<3;i++)//时,分,秒
Write_Ds1302_Byte(0x84-2*i,unRtc[i]/10*16+ucRtc[i]%10);
Write_Ds1302_Byte(0x8e,0x80);//开启写保护
}
//读取0x11 0x12 0x13 -> 11:12:13
void Read_Rtc(unsigned char* ucRtc)
{
unsigned char i;
unsigned char temp;
EA = 0;
for (i=0;i<3;i++)
{
temp=Read_Ds1302_Byte(0x85-2*i);
unRtc[i]=temp/16*10+temp%16;
}
EA = 1;
}
tips
void Read_Rtc(unsigned char* ucRtc)
{
EA = 0;
for (i=0;i<3;i++)
{
temp=Read_Ds1302_Byte(0x85-2*i);
unRtc[i]=temp/16*10+temp%16;
}
EA = 1;
}
Write_Ds1302_Byte(0x84-2*i,unRtc[i]/10*16+ucRtc[i]%10);
temp=Read_Ds1302_Byte(0x85-2*i);
unRtc[i]=temp/16*10+temp%16;
ds1302.h
#include <STC15F2K60S2.H>
void Set_Rtc(unsigned char* ucRtc);
void Read_Rtc(unsigned char* ucRtc);
数码管只做显示,外设独立
测试和使用
#include <STC15F2K60S2.H>
#include "ds1302.h"
pdata unsigned char ucRtc[3]={11,12,13};
idata unsigned char Time_Slow_Down;
void Seg_Proc()
{
if(Seg_Slow_Down<20)return;
Seg_Slow_Down=0;
Seg_Buf[0]=ucRtc[0]/10%10;
Seg_Buf[1]=ucRtc[0]%10;
Seg_Buf[2]=10;
Seg_Buf[3]=ucRtc[1]/10%10;
Seg_Buf[4]=ucRtc[1]%10;
Seg_Buf[5]=10;
Seg_Buf[6]=ucRtc[2]/10%10;
Seg_Buf[7]=ucRtc[2]%10;
}
void Get_Time()
{
if(Time_Slow_Down<100)return;
Time_Slow_Down=0;
Read_Rtc(ucRtc);
}
void Timer1_Isr(void) interrupt 3
{
Time_Slow_Down++;
}
void main()
{
System_Init();
Set_Rtc(ucRtc);
Timer1_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
Get_Time();
}
}
ds18b20(onewire)
ds18b20.c
/* # 单总线代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "onewire.h"
sbit DQ = P1^4;
//
void Delay_OneWire(unsigned int t)
{
unsigned char i;
while(t--){
for(i=0;i<12;i++);
}
}
//
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
float rd_Temperature()
{
unsigned char low,high;
init_ds18b20();
Write_DS18B20(0xcc);//skip
Write_DS18B20(0x44);//convert
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xcc);//skip
Write_DS18B20(0xbe);//read
low=Read_DS18B20();
high=Read_DS18B20();
return (float)(high<<8|low)*0.0625;
}
ds18b20.h
#include <STC15F2K60S2.H>
float rd_Temperature();
测试
#include <STC15F2K60S2.H>
#include "onewire.h"
idata unsigned int Temperature_10x;
idata unsigned int Temperature_Slow_Down;
void Get_Temperature()
{
if(Temperature_Slow_Down<300)return;
Temperature_Slow_Down=0;
Temperature_10x=rd_Temperature()*10;
}
void Timer1_Isr(void) interrupt 3
{
Temperature_Slow_Down++;
}
/*
void Delay750ms(void) //@12.000MHz
{
unsigned char data i, j, k;
i = 35;
j = 51;
k = 182;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
*/
void main()
{
// rd_Temperature();
// Delay750ms();
System_Init();
Set_Rtc(ucRtc);
Timer1_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
Get_Time();
Get_Temperature();
}
}
iic
iic.c
/* # I2C代码片段说明
1. 本文件夹中提供
的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "iic.h"
#include "intrins.h"
#define DELAY_TIME 5 //10
sbit sda=P2^1;
sbit scl=P2^0;
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
/*
4->DA
0x40/0x00 外部输入
0x41/0x01 光敏输入
0x42/0x02 差分输入
0x43/0x03 滑动输入
*/
unsigned char Ad_Read(unsigned char addr)
{
unsigned char temp;
I2CStart();
I2CSendByte(0x90);//选中pcf,写操作
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);//选中pcf,读操作
I2CWaitAck();
temp=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return temp;
}
//0~255->0~5
void Da_Write(unsigned char dat)
{
I2CStart();
I2CSendByte(0x90);//选中pcf,写操作
I2CWaitAck();
I2CSendByte(0x41);//写入Da使能
I2CWaitAck();
I2CSendByte(dat);//写入数字电压,转化模拟电压
I2CWaitAck();
}
//写入数组,写入起始位置,写入数据个数(uchar)
void EEPROM_Write(unsigned char* str,unsigned char addr,unsigned char num)
{
I2CStart();
I2CSendByte(0xa0);//选中AT24C02,写操作
I2CWaitAck();
I2CSendByte(addr);//起始地址
I2CWaitAck();
while(num--)
{
I2CSendByte(*str++);//写入每一位数据,指针递增,为下次准备
I2CWaitAck();
I2C_Delay(200);//保证完全写入
}
I2CStop();
I2C_Delay(255);
I2C_Delay(255);
I2C_Delay(255);
I2C_Delay(255);
I2C_Delay(255);
I2C_Delay(255);
I2C_Delay(255);
I2C_Delay(255);
I2C_Delay(255);
I2C_Delay(255);
}
//read数组,read起始位置,read数据个数(uchar)
void EEPROM_Read(unsigned char* str,unsigned char addr,unsigned char num)
{
I2CStart();
I2CSendByte(0xa0);//选中AT24C02,写操作
I2CWaitAck();
I2CSendByte(addr);//起始地址
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);//选中AT24C02,读操作
I2CWaitAck();
EA=0;
while(num--)
{
* str++=I2CReceiveByte();//read每一位数据
if(num)
I2CSendAck(0);
else
I2CSendAck(1);
}
I2CStop();
EA=1;
}
tips
#include "iic.h"
#include "intrins.h"
#define DELAY_TIME 5 //10
sbit sda=P2^1;
sbit scl=P2^0;
EA=0;
while(num--)
{
* str++=I2CReceiveByte();//read每一位数据
if(num)
I2CSendAck(0);
else
I2CSendAck(1);
}
I2CStop();
EA=1;
iic.h
#include <STC15F2K60S2.H>
unsigned char Ad_Read(unsigned char addr);
void Da_Write(unsigned char dat);
void EEPROM_Write(unsigned char* str,unsigned char addr,unsigned char num);
void EEPROM_Read(unsigned char* str,unsigned char addr,unsigned char num);
测试
万用表测试Da
#include <STC15F2K60S2.H>
#include "iic.h"
idata unsigned char Ad_1_Data_10x,Ad_3_Data_10x;
idata unsigned char AD_DA_Slow_Down;
pdata unsigned char EEPROM_Data_W[8]={9,8,7,6,5,4,3,2};
pdata unsigned char EEPROM_Data_R[8]={0,0,0,0,0,0,0,0};
void AD_DA()
{
if(AD_DA_Slow_Down<120)return;
AD_DA_Slow_Down=0;
Ad_1_Data_10x=Ad_Read(0x41)*10/51;
Ad_3_Data_10x=Ad_Read(0x43)*10/51;
Da_Write(3*51);
}
void Timer1_Isr(void) interrupt 3
{
AD_DA_Slow_Down++;
}
/*
void Delay750ms(void) //@12.000MHz
{
unsigned char data i, j, k;
i = 35;
j = 51;
k = 182;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
*/
void main()
{
// rd_Temperature();
// Delay750ms();
System_Init();
Set_Rtc(ucRtc);
EEPROM_Read(EEPROM_Data_R,0,8);
EEPROM_Write(EEPROM_Data_W,0,8);
EEPROM_Read(EEPROM_Data_R,0,8);
Timer1_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
Get_Time();
Get_Temperature();
AD_DA();
Get_Distance();
}
}
超声波
Ultrasound.c
测的不准换一下延时
练习官方版用注释的延时测得准
#include "Ultrasound.h"
#include "intrins.h"
sbit US_TX = P1^0;//发射
sbit US_RX = P1^1;//接收
//void Delay12us(void) //@12.000MHz
//{
// unsigned char data i;
// _nop_();
// _nop_();
// i = 33;//38
// while (--i);
//}
//Y1指令集更准
void Delay12us(void) //@12.000MHz
{
unsigned char data i;
_nop_();
i = 3;
while (--i);
}
void Ut_Wave_Init()
{
unsigned char i;
EA=0;
for(i=0;i<8;i++)
{
US_TX=1;
Delay12us();
US_TX=0;
Delay12us();
}
EA=1;
}
//v=340m/s=34000cm/s=0.034cm/us
//s=v*t/2=0.017t cm
unsigned char Ut_Wave_Data()
{
unsigned int time;
CMOD = 0X00;
CH = CL = 0;
Ut_Wave_Init();
CR=1;
while((US_RX==1)&&(CF==0));//没有接收且计数没有溢出
CR=0;
//接收到回波
if(CF==0)
{
time=CH<<8|CL;
return (time*0.017);
}
//溢出
else
{
CF=0;
return 0;
}
}
tips
延时在三个(38,33,3)里切换,正常测距应该有100
Ultrasound.h
#include <STC15F2K60S2.H>
unsigned char Ut_Wave_Data();
debug
#include <STC15F2K60S2.H>
#include "Ultrasound.h"
idata unsigned char Distance;
idata unsigned char Distance_Slow_Down;
void Get_Distance()
{
if(Distance_Slow_Down<150)return;
Distance_Slow_Down=0;
Distance=Ut_Wave_Data();
}
void Timer1_Isr(void) interrupt 3
{
Distance_Slow_Down++;
}
/*
void Delay750ms(void) //@12.000MHz
{
unsigned char data i, j, k;
i = 35;
j = 51;
k = 182;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
*/
void main()
{
// rd_Temperature();
// Delay750ms();
System_Init();
Set_Rtc(ucRtc);
EEPROM_Read(EEPROM_Data_R,0,8);
EEPROM_Write(EEPROM_Data_W,0,8);
EEPROM_Read(EEPROM_Data_R,0,8);
Timer1_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
Get_Time();
Get_Temperature();
AD_DA();
Get_Distance();
}
}
频率NE555
定时器0
使用P34
//测量频率必须注释P34的所有相关
特别注意:跳线帽连接sig和P34
#include <STC15F2K60S2.H>
idata unsigned int Freq;
idata unsigned int Time_1s;
void Timer0_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |=0x05;//开启计数器模式,且不自动重装
TL0 = 0x00; //设置计数初始值
TH0 = 0x00; //设置计数初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void Timer1_Isr(void) interrupt 3
{
if(++Time_1s==1000)
{
Time_1s=0;
Freq=(TH0<<8)|TL0;
TH0=TL0=0;
}
}
/*
void Delay750ms(void) //@12.000MHz
{
unsigned char data i, j, k;
i = 35;
j = 51;
k = 182;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
*/
void main()
{
//顺序不能轻易改变
// rd_Temperature();
// Delay750ms();
System_Init();
Set_Rtc(ucRtc);
EEPROM_Read(EEPROM_Data_R,0,8);
EEPROM_Write(EEPROM_Data_W,0,8);
EEPROM_Read(EEPROM_Data_R,0,8);
Timer0_Init();
Timer1_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
Get_Time();
Get_Temperature();
AD_DA();
Get_Distance();
}
}
Pwm
about
idata unsigned char Pwm_Period;//累积对比
idata unsigned char Pwm_Compare=6;//比较值,亮度
void Key_Proc()
{
if(Key_Slow_Down<10)return;
Key_Slow_Down=0;
Key_Val=Key_Read();
Key_Down=Key_Val&(Key_Val^Key_Old);
Key_Up=~Key_Val&(Key_Val^Key_Old);
Key_Old=Key_Val;
if(Key_Down==4)
Pwm_Compare=(++Pwm_Compare)%10;
}
void Led_Proc()
{
ucLed[0]=1;
ucLed[1]=0;
ucLed[2]=1;
ucLed[3]=0;
ucLed[4]=1;
ucLed[5]=0;
ucLed[6]=1;
ucLed[7]=0;
//Led_Disp(ucLed);
}
void Timer1_Isr(void) interrupt 3
{
Seg_Slow_Down++;
Key_Slow_Down++;
Time_Slow_Down++;
Temperature_Slow_Down++;
AD_DA_Slow_Down++;
Distance_Slow_Down++;
Seg_Pos=(++Seg_Pos)%8;
//底层没有20的下标(超出上限),加一个',',显示小数点
if(Seg_Buf[Seg_Pos]>20)
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]-',',1);
else
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],0);
if(++Time_1s==1000)
{
Time_1s=0;
Freq=(TH0<<8)|TL0;
TH0=TL0=0;
}
//Pwm
Pwm_Period=(++Pwm_Period)%10;
if(Pwm_Period<Pwm_Compare)
Led_Disp(ucLed);//不调光放在Led_Proc
else
Led_Off();
}
tips
//Pwm
Pwm_Period=(++Pwm_Period)%10;
if(Pwm_Period<Pwm_Compare)
Led_Disp(ucLed);//不调光放在Led_Proc
else
Led_Off();
Uart
串口波特率计算器
定时器2,12T,9600,12M
Uart.c
#include "Uart.h"
#include "stdio.h"
void Uart1_Init(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0xE6; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES = 1; //使能串口1中断
EA=1;
}
extern char putchar(char ch)
{
SBUF=ch;
while(TI==0)
;
TI=0;
return ch;
}
Uart.h
#include <STC15F2K60S2.H>
void Uart1_Init(void); //9600bps@12.000MHz
mian.c相关代码及其测试
#include <STC15F2K60S2.H>
#include "Uart.h"
#include "string.h"
#include "stdio.h"
idata unsigned char Uart_Rx_Index;
pdata unsigned char Uart_Rx_Buf[10]={0,0,0,0,0,0,0,0,0,0};
idata unsigned char Uart_Rx_Flag;
idata unsigned char Uart_Rx_Tick;//超时解析计时器
void Key_Proc()
{
if(Key_Slow_Down<10)return;
Key_Slow_Down=0;
Key_Val=Key_Read();
Key_Down=Key_Val&(Key_Val^Key_Old);
Key_Up=~Key_Val&(Key_Val^Key_Old);
Key_Old=Key_Val;
if(Key_Down==4)
Pwm_Compare=(++Pwm_Compare)%10;
if(Key_Down!=0)
printf("Key_Down:%bu",Key_Down);//发送
}
void Uart_Proc()
{
unsigned char x,y;
if(Uart_Rx_Index==0)return;
if(Uart_Rx_Tick>=10)
{
Uart_Rx_Flag=0;
Uart_Rx_Tick=0;
printf("%s",Uart_Rx_Buf);//回显,确保预期接收和真实接收一致
if(sscanf(Uart_Rx_Buf,"(%bu,%bu)",&x,&y)==2)
printf("\r\nI Get x=%bu,y=%bu\r\n",x,y);
else
printf("\r\nERROR\r\n");
memset(Uart_Rx_Buf,0,Uart_Rx_Index);
Uart_Rx_Index=0;
}
}
void Timer1_Isr(void) interrupt 3
{
if(Uart_Rx_Flag)
Uart_Rx_Tick++;
}
void Uart1_Isr(void) interrupt 4
{
if (RI) //检测串口1接收中断
{
Uart_Rx_Flag=1;
Uart_Rx_Tick=0;//重置计数器
Uart_Rx_Buf[Uart_Rx_Index++]=SBUF;
RI = 0; //清除串口1接收中断请求位
if(Uart_Rx_Index>10)
{
Uart_Rx_Index=0;
memset(Uart_Rx_Buf,0,10);
}
}
}
void main()
{
//顺序不能轻易改变
System_Init();
Set_Rtc(ucRtc);
EEPROM_Read(EEPROM_Data_R,0,8);
EEPROM_Write(EEPROM_Data_W,0,8);
EEPROM_Read(EEPROM_Data_R,0,8);
Timer0_Init();
Uart1_Init();
Timer1_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
Get_Time();
Get_Temperature();
AD_DA();
Get_Distance();
Uart_Proc();
}
}
help可以查bu
先检测一下printf,(用key),回显
正常后再把注释掉的Uart_Proc()开起来测试
串口是debug不了的
调度器版本
替换Slow_Down
idata unsigned long int uwTick;
void Timer1_Isr(void) interrupt 3
{
uwTick++;
}
typedef struct
{
void(*task_func)(void);
unsigned long int rate_ms;
unsigned long int last_ms;
}task_t;
idata task_t Scheduler_Task[]={
{Led_Proc,1,0},
{Key_Proc,10,0},
{Seg_Proc,20,0},
{Get_Time,100,0},
{Get_Temperature,300,0},
{AD_DA,150,0},
{Get_Distance,120,0},
{Uart_Proc,10,0},
};
idata unsigned char task_num;
void Scheduler_Init()
{
task_num=sizeof(Scheduler_Task)/sizeof(task_t);
}
void Scheduler_Run()
{
unsigned char i;
for(i=0;i<task_num;i++)
{
unsigned long int now_time=uwTick;
if(now_time>=(Scheduler_Task[i].rate_ms+Scheduler_Task[i].last_ms))
{
Scheduler_Task[i].last_ms=now_time;
Scheduler_Task[i].task_func();
}
}
}
void main()
{
//顺序不能轻易改变
System_Init();
Set_Rtc(ucRtc);
EEPROM_Read(EEPROM_Data_R,0,8);
EEPROM_Write(EEPROM_Data_W,0,8);
EEPROM_Read(EEPROM_Data_R,0,8);
Timer0_Init();
Scheduler_Init();
Uart1_Init();
Timer1_Init();
while(1)
{
Scheduler_Run();
}
}