TIM2_Init(); //三路pwm波初始化PD4,PD3,PA3.
exit_init(); //外部中断使能,PC1.
}
//1602.h
#include"canshu.h"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - 定义子程序函数
void LCD_init(void); // - - 初始化LCD1602函数
void LCD_write_command(uchar command); // - - 向LCD1602写指令函数
void LCD_write_data(uchar dat); // - - 向LCD1602写数据函数
void LCD_set_xy(uchar x,uchar y); // - - 设置LCD1602显示位置 X(0-16),y(1-2)
void LCD_disp_char(uchar x,uchar y,uchar dat); // - - 在LCD1602上显示一个字符
void LCD_disp_string(uchar X,uchar Y,uchar *s); // - - 在LCD1602上显示一个字符串
//void LCD_check_busy(void);//检查忙函数。我没用到此函数,因为通过率极低。
void LCD_delay_10us(uint n); // - - 10微秒的延时子程序
void LCD_delay_50us(uint n); // - - 50微秒的延时子程序
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void clock_hsi_16mhz(void)
{
CLK_ICKR|=0x01; //开启内部HSI
while(!(CLK_ICKR&0x02));//HSI准备就绪
CLK_SWR=0xe1; //HSI为主时钟源
CLK_CKDIVR=0x00; //HSI不分频
}
// - - 初始化LCD1602
void LCD_init(void)
{
LCD_delay_10us(20);
LCD_write_command(0x38); // - - 设置8位格式,2行,5x7
LCD_delay_10us(5);
LCD_write_command(0x0c); // - - 整体显示,关光标,不闪烁
LCD_delay_10us(5);
LCD_write_command(0x06); // - - 设定输入方式,增量不移位
LCD_delay_10us(5);
LCD_write_command(0x01); // - - 清除屏幕显示
LCD_delay_50us(40);
}
//********************************
// - - 向LCD1602写指令
void LCD_write_command(uchar dat)
{
LCD_delay_10us(5);
LCD_RS_LOW; // - - 指令
//LCD_RW_LOW; // - - 写入
DATAOUT=dat;
LCD_delay_10us(5);
LCD_EN_HIGH; // - - 允许
LCD_delay_10us(5);
LCD_EN_LOW;
}
// - - 向LCD1602写数据
void LCD_write_data(uchar dat)
{
LCD_delay_10us(5);
LCD_RS_HIGH;// - - 数据
//LCD_RW_LOW;// - - 写入
DATAOUT=dat;
LCD_delay_10us(5);
LCD_EN_HIGH;// - - 允许
LCD_delay_10us(5);
LCD_EN_LOW;
}
// - - 设置显示位置
void LCD_set_xy(uchar x,uchar y)
{
uchar address;
if(y==1)
{
address=0x80+x; // - - 第一行位置
} else {
address=0xc0+x; // - - 第二行位置
}
LCD_delay_10us(5);
LCD_write_command(address);
}
// - - 显示一个字符函数
void LCD_disp_char(uchar x,uchar y,uchar dat) // - - LCD_disp_char(0,1,0x38); // - - 显示8
{
LCD_set_xy(x,y);
LCD_delay_10us(5);
LCD_write_data(dat);
}
// - - 显示一个字符串函数
void LCD_disp_string(uchar x,uchar y,uchar *s)
{
LCD_set_xy(x,y);
LCD_delay_10us(5);
while(*s!='\0')
{
LCD_write_data(*s);
s++;
}
}
//********************************
/*******检查忙函数*************
void LCD_check_busy() //实践证明,在我的LCD1602上,检查忙指令通过率极低,以
{ //至于不能正常使用LCD。因此我没有再用检查忙函数。而使
do //用了延时的方法,延时还是非常好用的。我试了一下,用
{ LCD_E=0; //for循环作延时,普通指令只要1次循就可完成。清屏指令
LCD_RS=0; //要用200次循环便能完成。
LCD_RW=1;
LCD_DB=0xff;
LCD_E=1;
}while(LCD_DB^7==1);
}
******************************/
void LCD_delay_10us(uint n) // - - 10微秒的延时子程序
{
uint i,j;
for(i=n;i>0;i--)
for(j=4;j>0;j--);
}
void LCD_delay_50us(uint n) // - - 50微秒的延时子程序
{
uint i,j;
for(i=n;i>0;i--)
for(j=22;j>0;j--);
}
void LCD_GPIO_inint()
{
PA_DDR=0x0e;
PA_CR1=0x0e;
PA_CR2=0x0e;
PB_DDR=0xff;
PB_CR1=0xff;
PB_CR2=0xff;
PE_DDR=0x20;
PE_CR1=0x20;
PE_CR2=0x20;
PE_ODR&=0Xdf;
}
void dis_rads()
{
{
ulong pinjun_rads=0;
uchar i;
uint big_rads,small_rads;
for(i=0;i<9;i++)
{
if(last_rads[i]>last_rads[i+1])
{
big_rads=last_rads[i];
last_rads[i]=last_rads[i+1];
last_rads[i+1]=big_rads;
}
for(i=0;i<8;i++)
{
if(last_rads[i]<last_rads[i+1])
{
small_rads=last_rads[i];
last_rads[i]=last_rads[i+1];
last_rads[i+1]=small_rads;
}
}
for(i=1;i<9;i++)
pinjun_rads+= last_rads[i];
pinjun_rads/=8;
real_rads=(uint)(pinjun_rads);
}
}
uchar real_rad[4],set_rad[4];
LCD_disp_string(0,0,"S: ");
real_rad[0]=real_rads/1000+0x30;
real_rad[1]=real_rads%1000/100+0x30;
real_rad[2]=real_rads%1000%100/10+0x30;
real_rad[3]=real_rads%10+0x30;
set_rad[0]=set_rads/1000+0x30;
set_rad[1]=set_rads%1000/100+0x30;
set_rad[2]=set_rads%1000%100/10+0x30;
set_rad[3]=set_rads%10+0x30;
if(real_rads<1000)real_rad[0]=' ';
if(real_rads<100)real_rad[1]=' ';
if(real_rads<10)real_rad[2]=' ';
if(set_rads<1000)set_rad[0]=' ';
if(set_rads<100)set_rad[1]=' ';
if(set_rads<10)set_rad[2]=' ';
LCD_disp_string(2,0,set_rad);
LCD_disp_string(6,0,"r R: ");
LCD_disp_string(11,0,real_rad);
LCD_disp_char(15,0,'r');
}
//ds18b20.h
#include"canshu.h"
/******** STM8S-Discovery DS18B20 Test ********
* 版本.........: 1.0
* 作者.........: 陈利栋
* 目标.........: STM8S105C6
* 文件名.......: main.c
* 编译器.......: IAR for STM8 V1.1
* 创建时间.....: 2010.09.10
* 最后修改.....: 2010.09.10
**********************************************/
uchar wendu_buffer[5]={'0','0','.','0','C'};
unsigned char rom_code[8];
unsigned char const laseredrom[2][8]=
{
0x28,0xff,0x57,0x97,0x66,0x14,0x02,0xf4,
0x28,0xff,0xc9,0xd2,0x69,0x14,0x04,0x05,
};
uchar id[maxnum][8];
void _delay_us(unsigned int i)
{
i *= 3;
while(--i);
}
void _delay_ms(unsigned int i)
{
while(i--)
{
_delay_us(1000);
}
}
void DS18B20_Init(void)
{
DS18B20_DQ_OUT;
DS18B20_DQ_PUSH_PULL;
DS18B20_DQ_HIGH;
_delay_us(10);
DS18B20_DQ_LOW;
_delay_us(600); //复位脉冲
DS18B20_DQ_IN;
DS18B20_DQ_PULL_UP;
_delay_us(100);
while(DS18B20_DQ_VALUE == 1);
_delay_us(400);
}
void DS18B20_WriteByte(unsigned char _data)
{
unsigned char i = 0;
DS18B20_DQ_OUT;
for (i = 0; i < 8; i++)
{
DS18B20_DQ_LOW;
_delay_us(2);
if (_data & 0x01)
{
DS18B20_DQ_HIGH;
}
_data >>= 1;
_delay_us(60);
DS18B20_DQ_HIGH;
}
}
void DS18B2_WRITEBIT(uchar data)
{
DS18B20_DQ_OUT;
DS18B20_DQ_LOW;
if (data & 0x01)
{
DS18B20_DQ_HIGH;
}
_delay_us(60);
DS18B20_DQ_HIGH;
}
unsigned char DS18B20_2BITS(void)
{
unsigned char i,data=0;
for(i=0;i<2;i++)
{
DS18B20_DQ_OUT;
DS18B20_DQ_LOW;
_delay_us(5);
data<<=1;
DS18B20_DQ_HIGH;
DS18B20_DQ_IN;
if (DS18B20_DQ_VALUE)
data|=0x01;
DS18B20_DQ_OUT;
DS18B20_DQ_HIGH;
_delay_us(60);
}
return data;
}
unsigned char DS18B20_ReadByte(void)
{
unsigned char i = 0, _data = 0;
for (i = 0; i < 8; i++)
{
DS18B20_DQ_OUT;
DS18B20_DQ_LOW;
_delay_us(5);
_data >>= 1;
DS18B20_DQ_HIGH;
DS18B20_DQ_IN;
if (DS18B20_DQ_VALUE)
{
_data |= 0x80;
}
DS18B20_DQ_OUT;
DS18B20_DQ_HIGH;
_delay_us(60);
}
return _data;
}
float DS18B20_ReadTemperature(void)
{
unsigned char temp = 0;
float t = 0;
DS18B20_Init();
DS18B20_WriteByte(0xcc);
DS18B20_WriteByte(0x44);
DS18B20_Init();
DS18B20_WriteByte(0xcc);
DS18B20_WriteByte(0xbe);
temp = DS18B20_ReadByte();
t = (((temp & 0xf0) >> 4) + (temp & 0x07) * 0.125);
temp = DS18B20_ReadByte();
t += ((temp & 0x0f) << 4);
return t;
}
float DS18B20_ReadTemperature1(unsigned char j)
{
unsigned char i,temp = 0;
float t = 0;
DS18B20_Init();
DS18B20_WriteByte(0x55);
for(i=0;i<8;i++)
DS18B20_WriteByte(laseredrom[j][7-i]);
DS18B20_WriteByte(0x44);
DS18B20_Init();
DS18B20_WriteByte(0x55);
for(i=0;i<8;i++)
DS18B20_WriteByte(laseredrom[j][7-i]);
DS18B20_WriteByte(0xbe);
temp = DS18B20_ReadByte();
t = (((temp & 0xf0) >> 4) + (temp & 0x07) * 0.125);
temp = DS18B20_ReadByte();
t += ((temp & 0x0f) << 4);
return t;
}
float DS18B20_read(unsigned char i)
{
unsigned char j,temp = 0;
float t = 0;
DS18B20_Init();
DS18B20_WriteByte(0xcc);
DS18B20_WriteByte(0x44);
DS18B20_Init();
DS18B20_WriteByte(0x55);
for(j=0;j<8;j++)
{
DS18B20_WriteByte(id[i][j]);
}
DS18B20_WriteByte(0xbe);
temp = DS18B20_ReadByte();
t = (((temp & 0xf0) >> 4) + (temp & 0x07) * 0.125);
temp = DS18B20_ReadByte();
t += ((temp & 0x0f) << 4);
return t;
}
void read_rom_cmd(void)
{
unsigned char i;
DS18B20_Init();
DS18B20_WriteByte(0x33);
for(i=0;i<8;i++)
rom_code[i]= DS18B20_ReadByte();
}
void wendu_caculate()
{
int dis_wendu;
wendu=DS18B20_ReadTemperature();
dis_wendu=(int)(wendu*10);
wendu_buffer[0]=dis_wendu/100+0x30;
wendu_buffer[1]=dis_wendu%100/10+0x30;
wendu_buffer[3]=dis_wendu%10+0x30;
if(dis_wendu<100)
wendu_buffer[0]=' ';
wendu_buffer[2]='.';
if(dis_wendu>1000)
{
wendu_buffer[0]=dis_wendu/1000+0x30;
wendu_buffer[1]=dis_wendu%1000/100+0x30;
wendu_buffer[2]=dis_wendu%1000%100/10+0x30;
wendu_buffer[3]=' ';
}
if( dis_wendu>=330)
{
PE_ODR&=0Xdf;
PE_ODR|=0X20;
}
else
PE_ODR&=0Xdf;
}
//time.h
#include"canshu.h"
#include"1838.h"
//计数器模块
void TIM4_Init()
{
TIM4_IER=0x01;//启动中断
TIM4_EGR=0X01;//允许时能更新事件
TIM4_PSCR=0x07;// 计数器时钟=主时钟/128=16MHZ/128=125KHZ
TIM4_ARR=249;//自动装载值;定时周期=125khz/250≈2ms
TIM4_CNTR=249;//计数器初值
TIM4_CR1=0x01;//时能计数器
}
#pragma vector=TIM4_OVR_UIF_vector//0x19
__interrupt void TIM4_OVR_UIF_IRQHandler(void)//对应IAP的中断地址:0x8060
{
++cishu;
TIM4_SR=0x00;
if(cishu==29999)
{
cishu_flag=1;
cishu=0;
minute++;
ds1820_flag=0;
}
if(cishu%100==0)
pid_caculate();
}
void pid_caculate()
{
int ppk,ppi,ppd;
ppk=(int)((long)(((int)(pk*100))*(pid_error))/100);
ppi=(int)((long)(((int)(pi*100))*(pid_error-pid_error1))/100);
ppd=(int)((long)(((int)(pd*100))*(pid_dt1-pid_dt2))/100);
pid_out+=ppk+ppi+ppd;
if(pid_out>2000)pid_out=2000;
if(pid_out<1000)pid_out=1000;
TIM2_CCR1H =pid_out/256;
TIM2_CCR1L = pid_out%256;
}
//canshu.h
#include"iostm8s103K3.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar cishu_flag;
int cishu;
uint minute;
uint last_ms,now_ms;
uint last_rads[10],now_rads;
uint last_radss,last_radsss;
uint real_rads;
int set_rads;
uchar now_nus,last_nus;
int chaju_ms,chaju_nus;
uchar rads_flag;
uchar ds1820_flag;
uchar exit_flag;
uchar ir_real;
uchar ir_rads_flag;
uchar dis_flag;
char pid_flag1,pid_flag2;
int pid_error,pid_error1;
int pid_out;
int pid_dt1,pid_dt2;
float pk,pi,pd;
float wendu;
//1602参数设计
#define LCD_RS_OUT PA_DDR_DDR1 = 1 //输出
#define LCD_RW_OUT PA_DDR_DDR2 = 1 //输出
#define LCD_E_OUT PA_DDR_DDR3 = 1 //输出
#define LCD_RS_HIGH PA_ODR_ODR1 = 1 //拉高
#define LCD_RS_LOW PA_ODR_ODR1 = 0 //拉低
#define LCD_RS_PULL_UP PA_CR1_C11 = 1 //上拉
#define LCD_RS_FLOATING PA_CR1_C11 = 0 //浮空
#define LCD_RS_HIGH_SPEED PA_CR2_C21 = 1 //高速
#define LCD_RS_LOW_SPEEND PA_CR2_C21 = 0 //低速
/*
#define LCD_RW_HIGH PA_ODR_ODR2 = 1 //拉高
#define LCD_RW_LOW PA_ODR_ODR2 = 0 //拉低
#define LCD_RW_PULL_UP PA_CR1_C12 = 1 //上拉
#define LCD_RW_FLOATING PA_CR1_C12 = 0 //浮空
#define LCD_RW_HIGH_SPEED PA_CR2_C22 = 1 //高速
#define LCD_RW_LOW_SPEEND PA_CR2_C22 = 0 //低速
*/
#define LCD_EN_HIGH PA_ODR_ODR2 = 1 //拉高
#define LCD_EN_LOW PA_ODR_ODR2 = 0 //拉低
#define LCD_EN_PULL_UP PA_CR1_C12 = 1 //上拉
#define LCD_EN_FLOATING PA_CR1_C12 = 0 //浮空
#define LCD_EN_HIGH_SPEED PA_CR2_C22 = 1 //高速
#define LCD_EN_LOW_SPEEND PA_CR2_C22 = 0 //低速
#define DATAOUT PB_ODR
//ds18b20宏定义
#define DS18B20_DQ_OUT PF_DDR_DDR4 = 1 //输出
#define DS18B20_DQ_IN PF_DDR_DDR4 = 0 //输入
#define DS18B20_DQ_HIGH PF_ODR_ODR4 = 1 //拉高
#define DS18B20_DQ_LOW PF_ODR_ODR4 = 0 //拉低
#define DS18B20_DQ_PULL_UP PF_CR1_C14 = 1 //上拉
#define DS18B20_DQ_FLOATING PF_CR1_C14 = 0 //浮空
#define DS18B20_DQ_PUSH_PULL PF_CR1_C14 = 1 //推挽
#define DS18B20_DQ_OPEN_DRAIN PF_CR1_C14 = 0 //开漏
#define DS18B20_DQ_VALUE PF_IDR_IDR4 //DQ值
#define maxnum 2
//1838解码代码
#define KEY_0 0x16 //键0
#define KEY_1 0x0C //键1
#define KEY_2 0x18 //键2
#define KEY_3 0x5E //键3
#define KEY_4 0x08 //键4
#define KEY_5 0x1C //键5
#define KEY_6 0x5A //键6
#define KEY_7 0x42 //键7
#define KEY_8 0x52 //键8
#define KEY_9 0x4A //键9
#define prev 0x44 //电源
#define next 0x40 //模式
#define play_pause 0x43 //静音
#define chdel 0x45 //模式
#define ch 0x46
#define chadd 0x47 //模式
#define del 0x07
#define add 0x15
#define eq 0x09
#define add100 0x19
#define add200 0x0d
//1838.h
#include"canshu.h"
uchar IrRecStep = 0; //接收步骤
uchar IrIndex = 0; //接收位数
uchar IrRecFlag = 0; //接收完标志
uchar IrRecBuff[4]; //接收缓冲区
uchar IrRecAddr1; //红外地址码
uchar IrRecAddr2;
uchar IrRecData1; //红外数据码
uchar IrRecData2;
uint IrCycle = 0; //红外周期
uint IrHigh = 0; //占空比
const uchar IrCode[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//--------引导码低电平范围------------------
#define IrHeadLow_Max 2300 //2300*4 = 9200us
#define IrHeadLow_Min 2100 //2100*4 = 8400us
//--------引导码高电平范围------------------
#define IrHeadHigh_Max 1250 //1250*4 = 5000us
#define IrHeadHigh_Min 1050 //1050*4 = 4200us
//--------数据0的周期范围-------------------
#define IrData00_Max 300 //300*4 = 1200us
#define IrData00_Min 260 //260*4 = 1040us
//--------数据1的周期范围-------------------
#define IrData10_Max 580 //580*4 = 2320us
#define IrData10_Min 540 //540*4 = 2160us
//--------数据0的占空比(高电平)范围---------
#define IrData0_Max 160 //160*4 = 640us
#define IrData0_Min 120 //120*4 = 480us
//--------数据1的占空比(高电平)范围---------
#define IrData1_Max 440 //440*4 = 1760us
#define IrData1_Min 400 //400*4 = 1600us
//----------------------------------------------------------
#define REMOTE_CLK_DIV 63 //63+1=64----16Mh/64=4us
#define REMOTE_ICF_FILTER 0x30
//延时程序
void add_rad();
void set_rad();
void del_rad();
void lcd_display1();
void lcd_display2();
void Delay_ms( uint ms )
{
uint i,j;
for( j=0; j<ms; )
{
for( i=0; i<1000; i++ )
{;}
}
}
//红外接收端口初始化
void Ir_Init(void)
{
PC_DDR_DDR1 = 0; //PC1为输入
PC_CR1_C11 = 1;
PC_CR2_C21 = 0;
}
//使用TIM1的PWM输入捕获
void Ir_PWM_Init(void)
{
TIM1_PSCRH = 0;
TIM1_PSCRL = REMOTE_CLK_DIV;
TIM1_CCER1 &= 0xee;//禁止输入捕获1,2
TIM1_CCMR1 |= (REMOTE_ICF_FILTER + 0x01);// ch1到ti1fp1
TIM1_CCER1 &= 0xec;//ch1 上升沿触发
TIM1_CCMR2 |= (REMOTE_ICF_FILTER + 0x02);// ch2选择 ti1fp2上
TIM1_CCER1 |= 0x20;//ch1 下降沿触发 ic2
TIM1_SMCR |= 0x54;//选源触发源和触发方式 复位
TIM1_CCER1 |= 0x11;//使能输入捕获1,2
TIM1_CR1 |= 0x05;
}
//红外接收程序
void Ir_Receive(void)
{
switch(IrRecStep)
{
case 0:
IrIndex = 0;
if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1))
{
IrHigh = (uint)(TIM1_CCR2H);
IrHigh = (IrHigh << 8) + TIM1_CCR2L; //IrHigh占空比
IrCycle = (uint)(TIM1_CCR1H);
IrCycle = (IrCycle << 8) + TIM1_CCR1L; //IrCycle周期
//是否在引导码低电平范围内
if (((IrCycle - IrHigh) < IrHeadLow_Max)&&((IrCycle - IrHigh) > IrHeadLow_Min))
{
IrRecStep = 1;
TIM1_SR1_CC1IF = 0;
TIM1_SR1_CC2IF = 0;
TIM1_SR2_CC1OF = 0;
TIM1_SR2_CC2OF = 0;
TIM1_SR1_UIF = 0;
IrRecBuff[0] = 0;
IrRecBuff[1] = 0;
IrRecBuff[2] = 0;
IrRecBuff[3] = 0;
}
}
break;
case 1:
if ((TIM1_SR2_CC1OF==1) || (TIM1_SR2_CC2OF==1) || (TIM1_SR1_UIF==1))
{
IrRecStep = 0;
}
else
{
if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1))
{
IrHigh = (uint)(TIM1_CCR2H);
IrHigh = (IrHigh << 8) + TIM1_CCR2L;
IrCycle = (uint)(TIM1_CCR1H);
IrCycle = (IrCycle << 8) + TIM1_CCR1L;
//是否在引导码高电平范围内
if ((IrHigh < IrHeadHigh_Max)&&(IrHigh > IrHeadHigh_Min))
{
IrRecStep = 2;
}
}
}
break;
case 2:
if ((TIM1_SR2_CC1OF==1) || (TIM1_SR2_CC2OF==1) || (TIM1_SR1_UIF==1))
{
IrRecStep = 0;
}
else
{
if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1))
{
IrHigh = (uint)(TIM1_CCR2H);
IrHigh = (IrHigh << 8) + TIM1_CCR2L;
IrCycle = (uint)(TIM1_CCR1H);
IrCycle = (IrCycle << 8) + TIM1_CCR1L;
//周期是否在数据0范围内
if ((IrCycle > IrData00_Min)&&(IrCycle < IrData00_Max))
{
//高电平是否在数据0范围内
if ((IrHigh > IrData0_Min)&&(IrHigh < IrData0_Max))
{
IrIndex++;
}
else
{
IrRecStep = 0;
}
}
//周期是否在数据1范围内
else if ((IrCycle > IrData10_Min)&&(IrCycle < IrData10_Max))
{
//高电平是否在数据1范围内
if ((IrHigh > IrData1_Min)&&(IrHigh < IrData1_Max))
{
IrRecBuff[IrIndex >> 3] |= IrCode[IrIndex & 0x07];
IrIndex++;
}
else
{
IrRecStep = 0;
}
}
else
{
IrRecStep = 0;
}
if(IrIndex >= 32)
{
IrRecStep = 0;
IrRecFlag = 1;
}
}
}
break;
}
}
//时钟初始化
void CLK_Init(void)
{
CLK_ECKR=0x03;//外部时钟寄存器 外部时钟准备就绪,外部时钟开
CLK_SWCR=0x02;//切换控制寄存器 使能切换机制
CLK_SWR=0xB4;//主时钟切换寄存器 选择HSE为主时钟源*/
while (!(CLK_SWCR & 0x08));
CLK_CSSR=0x01;//时钟安全系统寄存器
}
//初始化
void Devices_Init(void)
{
Delay_ms(200);
CLK_Init();
Ir_Init();
Ir_PWM_Init();
}
void set_rad()
{
if(dis_flag==0)
{
++ir_rads_flag;
if(ir_rads_flag==4)
ir_rads_flag=0;
}
if(dis_flag==2)
{
++pid_flag1;
if(pid_flag1==4)
pid_flag1=0;
}
}
void add_rad()
{
if(dis_flag==0)
{
switch(ir_rads_flag)
{
case 0:set_rads+=1;break;
case 1:set_rads+=10;break;
case 2:set_rads+=100;break;
case 3:set_rads+=1000;break;
default:break;
}
if(set_rads>=10000)set_rads=9999;
}
if(dis_flag==2)
{
switch(pid_flag1)
{
case 0:
switch(pid_flag2)
{
case 0:pk+=0.01;break;
case 1:pi+=0.01;break;
case 2:pd+=0.01;break;
default:break;
}
break;
case 1:
switch(pid_flag2)
{
case 0:pk+=0.1;break;
case 1:pi+=0.1;break;
case 2:pd+=0.1;break;
default:break;
}
break;
case 2:
switch(pid_flag2)
{
case 0:pk+=1;break;
case 1:pi+=1;break;
case 2:pd+=1;break;
default:break;
}
break;
case 3:
switch(pid_flag2)
{
case 0:pk+=10;break;
case 1:pi+=10;break;
case 2:pd+=10;break;
default:break;
}
break;
default:break;
}
if(pk>9999)pk=9999;
if(pi>9999)pi=9999;
if(pd>9999)pd=9999;
}
}
void del_rad()
{
if(dis_flag==0)
{
switch(ir_rads_flag)
{
case 0:set_rads-=1;break;
case 1:set_rads-=10;break;
case 2:set_rads-=100;break;
case 3:set_rads-=1000;break;
default:break;
}
if(set_rads<1)set_rads=0;
}
if(dis_flag==2)
{
switch(pid_flag1)
{
case 0:
switch(pid_flag2)
{
case 0:pk-=0.01;break;
case 1:pi-=0.01;break;
case 2:pd-=0.01;break;
default:break;
}
break;
case 1:
switch(pid_flag2)
{
case 0:pk-=0.1;break;
case 1:pi-=0.1;break;
case 2:pd-=0.1;break;
default:break;
}
break;
case 2:
switch(pid_flag2)
{
case 0:pk-=1;break;
case 1:pi-=1;break;
case 2:pd-=1;break;
default:break;
}
break;
case 3:
switch(pid_flag2)
{
case 0:pk-=10;break;
case 1:pi-=10;break;
case 2:pd-=10;break;
default:break;
}
break;
default:break;
}
if(pk<0)pk=0;
if(pi<0)pi=0;
if(pd<0)pd=0;
}
}
void pid_add_flag2()
{
if(dis_flag==2)
{
++pid_flag2;
if(pid_flag2>=3)
pid_flag2=0;
}
}
void lcd_display1()
{
if(cishu%500==0)
{
uchar dis_t[5];
uchar time_dis[8];
dis_t[0]=t/10000+0x30;
dis_t[1]=t%10000/1000+0x30;
dis_t[2]=t%10000%1000/100+0x30;
dis_t[3]=t%10000%1000%100/10+0x30;
dis_t[4]=t%10+0x30;
if(t<10000)dis_t[0]=' ';
if(t<1000)dis_t[1]=' ';
if(t<100)dis_t[2]=' ';
time_dis[0]=minute/60/10+0x30;
time_dis[1]=minute/60%10+0x30;
time_dis[2]=':';
time_dis[3]=minute%60/10+0x30;
time_dis[4]=minute%60%10+0x30;
time_dis[5]=':';
time_dis[6]=t*2/1000/10+0x30;
time_dis[7]=t*2/1000%10+0x30;
if(minute<600)time_dis[0]=' ';
if(minute<60)
{
time_dis[1]=' ';
time_dis[2]=' ';
}
if(minute<10)time_dis[3]=' ';
if(t<5000)time_dis[3]=' ';
LCD_disp_string(0,1,"t: ");
LCD_disp_string(2,1,dis_t);
LCD_disp_char(8,1,ir_real);
LCD_disp_string(0,0,"time: ");
LCD_disp_string(5,0,time_dis);
LCD_disp_string(13,0," ");
LCD_disp_string(9,1," ");
}
}
void lcd_display2()
{
if(cishu%500==0)
{
uchar p[5],i[5],d[5];
int pp,ii,dd;
pp=(int)(pk*100);
ii=(int)(pi*100);
dd=(int)(pd*100);
p[0]=pp/1000+0x30;
p[1]=pp%1000/100+0x30;
p[2]='.';
p[3]=pp%1000%100%10+0x30;
p[4]=pp%10+0x30;
i[0]=ii/1000+0x30;
i[1]=ii%1000/100+0x30;
i[2]='.';
i[3]=ii%1000%100%10+0x30;
i[4]=ii%10+0x30;
d[0]=dd/1000+0x30;
d[1]=dd%1000/100+0x30;
d[2]='.';
d[3]=dd%1000%100%10+0x30;
d[4]=dd%10+0x30;
if(pp<1000)p[0]=' ';
if(ii<1000)i[0]=' ';
if(dd<1000)d[0]=' ';
LCD_disp_string(0,1,"P: ");
LCD_disp_string(2,1,p);
LCD_disp_string(7,1," ");
LCD_disp_string(9,1,"I: ");
LCD_disp_string(11,1,i);
LCD_disp_string(0,0,"D: ");
LCD_disp_string(2,0,d);
LCD_disp_char(7,0,' ');
LCD_disp_char(8,0,ir_real);
LCD_disp_string(9,0," ");
LCD_disp_char(10,0,pid_flag1+0x30);
switch(pid_flag2)
{
case 0: LCD_disp_char(12,0,'P');break;
case 1:LCD_disp_char(12,0,'I');break;
case 2:LCD_disp_char(12,0,'D');break;
default:LCD_disp_char(12,0,' ');break;
}
}
}
//pwm.h
#include"canshu.h"
void pid_caculate();
uint t;
void TIM2_Init()
{
TIM2_CCMR2 = TIM2_CCMR2 | 0x70;// Output modePWM2.
//通道2被设置成比较输出方式
// OC2M = 111,为PWM模式2,
// 向上计数时,若计数器小于比较值,为无效电平
// 即当计数器在0到比较值时,输出为1,否则为0
TIM2_CCMR1 = TIM2_CCMR1 | 0x70;
TIM2_CCMR3 = TIM2_CCMR3 | 0x70;
TIM2_CCER1 = TIM2_CCER1 | 0x33;// CC polarity low,enable PWMoutput */
// CC2P = 1,低电平为有效电平
// CC2E = 1,开启输出引脚
TIM2_CCER2 = TIM2_CCER2 | 0x03;
//初始化自动装载寄存器,决定PWM方波的频率,Fpwm=16000000/1000=16kHZ
TIM2_ARRH = 16000/255;
TIM2_ARRL = 16000%255;
TIM2_CCR1H =1000/255;
TIM2_CCR1L = 1000%255;
//初始化比较寄存器,决定PWM方波的占空比
TIM2_CCR2H =1000/255;
TIM2_CCR2L =1000%255;
TIM2_CCR3H = 1000/256;
TIM2_CCR3L = 1000%256;
//初始化时钟分频器为1,即计数器的时钟频率为Fmaster=4MHZ
TIM2_PSCR =0x00;//因为用了继电器,所以哟分频,可到0x08,256分频
//启动计数
TIM2_CR1 = TIM2_CR1 | 0x01;
}
//外部中断触发
void exit_init()
{
PC_DDR&=~0x04;
PC_CR1|=0x04;
PC_CR2|=0x04;
EXTI_CR1|= 0x10;
}
#pragma vector=0x07 // 这里很关键!看下面说明。
__interrupt void EXTI_PC1(void)
{
asm("sim");
switch(EXTI_CR1)
{
case 0x10:EXTI_CR1=0x20;exit_flag=1;break;
case 0x20:EXTI_CR1=0x10;exit_flag=2;break;
default :exit_flag=0;break;
}
if(exit_flag==2)
{
t++;
exit_flag=0;
if(t%10==0)
{
ulong chaju;
now_nus=TIM4_CNTR;
now_ms=cishu;
chaju_ms=now_ms-last_ms;
if(cishu_flag==1)
{
cishu_flag=0;
chaju_ms=30000+now_ms-last_ms;
}
chaju_nus=now_nus-last_nus;
chaju=chaju_ms*250+chaju_nus;
now_rads=(1250000/chaju);
last_nus=now_nus;
last_ms=now_ms;
last_rads[rads_flag++]=now_rads;
if(rads_flag==10)
rads_flag=0;
pid_error1=pid_error;
pid_error=set_rads-now_rads;
pid_dt2=pid_dt1;
pid_dt1=pid_error-pid_error1;
last_radsss=last_radss;
last_radss =now_rads;
}
}
asm("rim");
}
#pragma vector=TIM2_OVR_UIF_vector
__interrupt void TIM3_OVF_IRQHandler(void)
{
TIM2_SR1 = 0x00;
ds1820_flag=1;
}
//定时器2产生60s的中断
void TIM2_time()
{
TIM2_EGR=0x01; //手动产生更新事件,重新初始化计数器,并允许产生一个更新事件
//设置定时器初值
TIM2_CNTRH=0; //不能使用TIM3_CNTR直接设值,
TIM2_CNTRL=0;
//设定自动重装寄存器值
//这里得注意不能使用TIM2_ARR的方式进行设值,TIM2是十六位的。
//如TIM2_ARR=0xFA,实际上是赋给高字节了,TIM2_ARRH=0xFA,而不是想象中的赋给低字节。
TIM2_ARRH=0x72; //488hz 488 /29280 = 60s (1S)
TIM2_ARRL=0x60; //0x007d 意味着每产生一次中断时间为60S
TIM2_PSCR=0x0f; //预分频32275
TIM2_IER=0x01; //中断允许位使能
TIM2_CR1=0x01; //使能计时器
}