首先读题可知我们需要初始化led,数码管,ds18b20模块,pwm也就是定时器模块,
代码如下:
数码管的
#include "smg.h"
uchar code t_display[]={ //标准字库
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x00,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
uchar code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
//共阳给7低电平亮,给6高电平亮
void smg_display(uchar wei,duan,dian)
{
P0 = 0xff;
hc573(7);
P0 = 0x01<<wei;
hc573(6);
if(!dian) P0 = ~t_display[duan];
else P0 = ~(t_display[duan]|0x80);
hc573(7);
Delay_1ms(1);
}
按键的:
#include "key.h"
uchar key_count = 0;
//p30 p31 p32 p33
//s7 s6 s5 s4
uchar key_had(void)//这里加个标志位否则反复进来
{
if(key_count==1 && (P30==0||P31==0||P32==0||P33==0))
{
key_count = 0;
Delay_1ms(50);
if(P30==0)return 7;
if(P31==0)return 6;
if(P32==0)return 5;
if(P33==0)return 4;
}
else if(P30==1&&P31==1&&P32==1&&P33==1)
{
key_count = 1;
}
return 0;
}
温度模块:
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台
日 期: 2011-8-9
*/
#include "onewire.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
t = t*12;
while(t--);
}
//DS18B20芯片初始化
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;
}
//通过单总线向DS18B20写一个字节
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);
}
//从DS18B20读取一个字节
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;
}
unsigned int ds18b20(uchar dot)
{
uchar templ,temph;
uint temp;
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
templ = Read_DS18B20();
temph = Read_DS18B20();
temp = (temph<<8)|templ;
switch(dot)
{
case 0:temp = temp * 0.0625;break;
case 1:temp = temp * 0.625;break;
case 2:temp = temp * 6.25;break;
}
return temp;
}
定时器:
#include "timer.h"
uint miao=50;
//1KHZ->1/1000的频率,T等于1/1000的时间所以是0.1ms因为频率是1ms而要改pwm波所以定时0.1ms然后计数10次
uchar count = 0;
uint count1 = 1000;
void Timer0_Isr(void) interrupt 1
{
count++;
if(count==10)count=0;
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
void pwm_control(uchar num)
{
if(count<=num)
{
P34 = 1;
}
else
{
P34 = 0;
}
}
void Timer1_Isr(void) interrupt 3
{
count1--;
if(count1==0)
{
miao--;count1=1000;
}
}
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x20; //设置定时初始值
TH1 = 0xD1; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
}
定时器这里需要注意题目要求信号频率1Khz,所以我们的周期为1ms,而要输出pwm那就需要给定周期,我们在0.1ms的定时器基础上去计数来形成pwm波,那么输出的pwm周期为1ms。
最终代码在文章最后
我们需要制作两个数码管界面一个是电机pwm输出另一个是显示温度的界面,其次是S7按键去切换两个模式,如果直接判断那就会出现切换不了因为切换到另一个模式后S7还是按下的状态会切换回去,所以我们在函数外去定义一个标志位,用标志位去切换两个模式,其他的没有什么难度了。
主程序代码:
#include "STC15.h"
#include "sys.h"
#include "smg.h"
#include "key.h"
#include "timer.h"
#include "onewire.h"
uchar S6=0;S7=0,S45=1;
uchar pattern=1;
extern uint miao;
uchar num=0,num_old=1;
uint tem=0;
void smg_pwm(void)
{
if(num_old%2==1)
{
smg_display(0,17,0);
smg_display(1,pattern,0);
smg_display(2,17,0);
smg_display(3,18,0);
smg_display(4,miao/1000,0);
smg_display(5,miao%1000/100,0);
smg_display(6,miao%100/10,0);
smg_display(7,miao%10,0);
if(num==4)
{
pattern++;if(pattern==4)pattern=1;
}
if(num==5)
{
miao+=60;
}
if(num==6)
{
miao=0;
}
if(pattern==1)
{
pwm_control(2);
if(miao!=0)
{
P0=0xfe;
hc573(4);
}
}
if(pattern==2)
{
pwm_control(3);
if(miao!=0)
{
P0=0xfd;
hc573(4);
}
}
if(pattern==3)
{
pwm_control(7);
if(miao!=0)
{
P0=0xfb;
hc573(4);
}
}
if(miao==0)
{
EA=0;
P0=0xff;
hc573(4);
}
else EA=1;
}
}
void S7_cufa(void)
{
if(num_old%2==0)
{
tem = ds18b20(0);
smg_display(0,17,0);
smg_display(1,4,0);
smg_display(2,17,0);
smg_display(3,18,0);
smg_display(4,18,0);
smg_display(5,tem/10,1);
smg_display(6,tem%10,1);
smg_display(7,12,0);
}
}
void main(void)
{
sysinit();
Timer0_Init();
Timer1_Init();
while(1)
{
num = key_had();
smg_pwm();
S7_cufa();
if(num==7)
{
num_old++;
}
// tem = ds18b20(0);
// smg_display(0,tem/10,1);
// smg_display(1,tem%10,1);
//P34 = 1;
}
}