430 likes | 632 Views
第六章 微机高级应用实例. 实例 1 : LED 照明灯. 驱动 LED 并实时监控亮度 恒流驱动. LT3478. PWM 调光, 3000:1 不会导致与电流有关的 LED 色彩变化。 LED 的导通时间 ( 或者平均电流 ) 受控于 PWM 引脚的占空比。 由于 LED 始终工作于相同的电流条件下,而只有平均电流发生变化,所以调光不会导致 LED 的色彩改变。. CTRL1 = 1.24* 130/(130+45.3+54.9) = 0.7V. 电流监控 INA139. ADC —— ADS7822. 12 位 ADS7822 功能特点:
E N D
实例1:LED照明灯 • 驱动LED并实时监控亮度 • 恒流驱动
LT3478 • PWM调光,3000:1 • 不会导致与电流有关的LED色彩变化。 • LED的导通时间(或者平均电流)受控于PWM引脚的占空比。 • 由于LED始终工作于相同的电流条件下,而只有平均电流发生变化,所以调光不会导致LED的色彩改变。
ADC —— ADS7822 • 12位ADS7822功能特点: • 采样速率可达75 kHz ; • 单电源供电,可以在2. 0~5. 0 V 的电源电压下工作,范围广; • 微功耗:采样速率75kHz 时为0. 54 mW;7. 5kHz时为0. 06 mW;掉电模式时,最大电流为3μA ; • 体积小,有8 脚DIP ,SOIC 及MSOP 封装; • 模拟信号可单端或差分输入; • 采用串行方式和与CPU 相连。
ADS7822工作原理 • 内部框图 • 转换时序图
/************读取电压值***************/ long GetLM(void) { uchar i,j,hbyte,lbyte; uint ADdata=0; //ADdata转换一次的数据,AD_data转换后的平均数据; long AD_data=0; LM_CS=1; // for(i=0;i<=127;i++) //转换128次取平均值 { DCLK=0; //ad DCLK为低电平 LM_CS=0; //开始A/D转换 hbyte=0; //清高字节 delay(5); for(j=0;j<3;j++) // 三周期后开始读入数据 { DCLK=0; delay(1); DCLK=1; delay(1); }
for(j=0;j<=3;j++) { DCLK=0; //低电平时读数据 delay(1); if(LM_IN==1) //若是1 相应位置1 hbyte|=(1<<(3-j)); DCLK=1; delay(1); } lbyte=0; //清低字节 for(j=0;j<=7;j++) { DCLK=0; //低电平时读数据 delay(1); if(LM_IN==1) lbyte|=(1<<(7-j)); //若是1 相应位置1 DCLK=1; delay(1); } LM_CS=1; //转换结束 ADdata=(uint)(hbyte<<8)|lbyte; //高四位 低八位合成 AD_data+=(ADdata&0x0fff); feed_watchdog(); } AD_data = AD_data>>7; //除以128,求平均 return AD_data; }
实例2:数码彩扩冲印机 • 用数码手段,在化学相纸上曝光成像的设备和技术。 • 数码彩扩步骤:数据采集、数据处理、数码曝光、冲纸。 • 优点: • 解决了数码相机无底片问题; • 所见即所得,照片效果预先在显示终端上得到,可进行个性化设计,控制和改进最终输出的效果; • 良好的图像色彩还原性,图像质量高于除印刷以外的其他方式; • 数码相机可随拍随洗; • 可通过网络进行图像的存储和交换,实现网上冲印服务。
AD590及温度AD采样 • Linear Current Output: 1 A/K • Wide Range: –55 C to +150C • Two Terminal Device: Voltage In/Current Out • Excellent Linearity: ±0.3 C Over Full Range (AD590M) • Wide Power Supply Range: +4 V to +30 V
电路设计 0°输出273A, 10V/0.273mA = 36.6K
电路设计 2.5V/0.273mA = 9.15K
ADC初始化 void init_adc(void) { ADC0CN = 0x81; // ADC0 enabled; normal tracking // mode; ADC0 conversions are initiated // on write to AD0BUSY; ADC0 data is // left-justified REF0CN = 0x07; // enable temp sensor, on-chip VREF, // and VREF output buffer AMX0CF = 0; //AIN0~AIN7 均单端使用 ADC0CF = 0x80; // ADC conversion clock = 16 晶振时钟, <1us 在11.0592MHz EIE2 &= ~0x02; // disable ADC0 End of Conversion interrupt EIE1 &= ~0x04; // disable ADC0 window compare interrupt }
温度转换 unsigned int read_temp(unsigned char Channel) //Channel 0: CX; 1: PD; 2: WD; 3: HG { unsigned int xdata i; unsigned int xdata Temp; //存放 温度ADC值。 unsigned int xdata Ctg; //最终摄氏温度 AMX0SL = Channel; //温度传感器输入 Temp = 0; for(i=0;i<100;i++) { ADCINT = 0; // clear conversion complete indicator ADBUSY = 1; // initiate conversion while (ADCINT == 0); // wait for conversion complete Temp += ADC0H; //只获取高8位AD转换值,据此计算相应温度 } if(Channel<=2) //前三个通道为彩显、漂定和稳定 Ctg =(unsigned int)((((float)Temp/100.0)/256.0)*(float)VREF/4.9);//求100次平均值。每0.1摄氏度4.9mV else Ctg =(unsigned int)((((float)Temp/100.0)/256.0)*(float)VREF/2.45);//求100次平均值。每0.1摄氏度2.45mV return Ctg; }
温度控制 • void Temp_Control_HG(void) • { • char xdata i; • //实际温度比设置温度低5度以上,连续加热 • if(Temp_HG_Read+Temp_HG_Offset<Temp_HG_Set-Temp_Paper_Threshold) • { • HG_HEATER=0; //加热 • } • //实际温度比设置温度低5度以内,占空比加热 • if((Temp_HG_Read+Temp_HG_Offset>=Temp_HG_Set-Temp_Paper_Threshold) & (Temp_HG_Read+Temp_HG_Offset<Temp_HG_Set-10)) { • PWM_Heat(3,PWM_persent); //占空比加热 • } • //实际温度在设置温度±1度以内,占空比加热 • if((Temp_HG_Read+Temp_HG_Offset>=Temp_HG_Set-10) & (Temp_HG_Read+Temp_HG_Offset<Temp_HG_Set+10)) • { • PWM_Heat(3,4); //占空比加热 • } • //大于实际温度,但在10度之内,停止加热 • if ((Temp_HG_Read+Temp_HG_Offset>=Temp_HG_Set+10) & (Temp_HG_Read+Temp_HG_Offset<Temp_HG_Set+100)) • HG_HEATER=1; //停止 • }
if(Temp_HG_Read+Temp_HG_Offset>=Temp_HG_Set+100) //实际温度比设置温度高10度,报警if(Temp_HG_Read+Temp_HG_Offset>=Temp_HG_Set+100) //实际温度比设置温度高10度,报警 • { • HG_HEATER=1; //停止 • if(Alarm_Num<=ALIMIT) • { • ALARM=0; //停止报警 • if(Alarm_Num==1) • { • LCD_WriteCommand(2,0xB8+6); //纵向起始位置(行数)第7页 • LCD_WriteCommand(2,0x40); //横向起始位置 (列) • for (i=0;i<32;i++) • LCD_WriteData(2,0x0); //隐藏实际测量“烘干”温度 • LCD_WriteCommand(2,0xB8+7); //纵向起始位置(行数)第8页 • LCD_WriteCommand(2,0x40); //横向起始位置 (列) • for (i=0;i<32;i++) • LCD_WriteData(2,0x0); //隐藏实际测量“烘干”温度 • } • Alarm_Num++; • } • else if(Alarm_Num<=2*ALIMIT) • { • ALARM=1; //报警 • if(Alarm_Num==ALIMIT+1) //显示实际测量烘干温度 LCD_WriteNum(2,0,6,(Temp_HG_Read+Temp_HG_Offset)/10.0); • Alarm_Num++; • } • else • Alarm_Num=0; • }
void Temp_Control_NoHG(void) //彩显、漂定、稳定温度控制 { char xdata i; if(Temp_CX_Read+Temp_CX_Offset<Temp_CX_Set-Temp_Threshold) { //实际温度比设置温度低Temp_Threshold度以上,连续加热 if(Yeiwei_Low_CX!=LOW_FLAG) //彩显槽中液位不为低时加热 CX_HEATER=0; //加热 else CX_HEATER=1; //stop 加热 } else if(Temp_CX_Read+Temp_CX_Offset>=Temp_CX_Set-Temp_Threshold & Temp_CX_Read+Temp_CX_Offset<Temp_CX_Set) { //实际温度在Temp_Threshold与设置温度低以内,占空比加热 if(Yeiwei_Low_CX!=LOW_FLAG) //彩显槽中液位不为低时加热 PWM_Heat(0,PWM_persent); //占空比加热 else CX_HEATER=1; //stop 加热 } else if (Temp_CX_Read+Temp_CX_Offset>=Temp_CX_Set & Temp_CX_Read+Temp_CX_Offset<Temp_CX_Set+30) {//大于实际温度,但在3度之内,停止加热 CX_HEATER=1; //停止 } else if(Temp_CX_Read+Temp_CX_Offset>=Temp_CX_Set+30) //实际温度比设置温度高3度,报警
可靠性设计:TPS3705 • Power-On Reset Generator with Fixed Delay Time of 200 ms, no External Capacitor Needed • Precision Supply Voltage Monitor 2.5 V, 3 V, 3.3 V, and 5 V • Integrated Watchdog Timer • Voltage Monitor for Power-Fail or Low-Battery Warning
TPS3705 WDI = !WDI; //触发外部看门狗 if(!WDO) //外部看门狗低电平 { ALARM=1; //报警 EIE2 &= 0xFE; //关闭定时器3中断,使片内看门狗溢出复位 }
void Timer3_ISR() interrupt 14 //Timer3 interrupt { TMR3CN &= 0x7F; //清除中断标志 WDTCN = 0xA5; // Watchdog Timer Control Register,允许并重载 WDTCN = 0x07; //时间间隔 1048576/系统频率 (11.0592MHz, 95ms) if(!Paper_Flag) //若停止冲纸,延时计数开始 Paper_Num++; //冲纸计数加1 if(Display_Num%5 == 0) { LIGHT = 0; //指示灯灭 } else { LIGHT = 1; //指示灯亮 } }
L297+L298 • L297单片步进电机控制集成电路适用于双极性两相步进电机或单极性四相步进电机的控制 • L298为H桥式驱动芯片 • L297+L298组合成完整的步进电机恒流斩波驱动器 • 使用L297的突出特点是外部只需时钟、方向和工作方式3个输入信号,L297自动产生电机励磁相序。
//送纸子程序 void In_Motor(unsigned int Step_Num, unsigned int Speed) { unsigned int i; FixStep = FIXSTEP; //固定步长为400步,用于缓启动和缓停止 if((Step_Num <= 15) || (Step_Num>1000)) //若步长太大或太小,返回 return; Step_Num *= STEP_COEF; //输入步长乘系数转换为提升电机正确步数 Step_Num -= (FixStep+FixStep/2); //运行步长减去缓启动和缓停止的步长 //送纸至切刀前先将前面曝光好的相纸走出 PAPER_OUT_EN =ENABLE; //使能出纸步进电机 PAPER_OUT_CW = CW; //顺时针转 ExtWatchdog(); //外部看门狗操作 for(i=200;i>0;i--) //出纸前200步慢启动 { PAPER_OUT_CLK =1; //正脉冲 delay2us(Speed+Speed*(i/20)); //缓慢启动,20个脉冲一档 PAPER_OUT_CLK =0; //负脉冲 delay2us(Speed+Speed*(i/20)); //缓慢启动,20个脉冲一档 ExtWatchdog(); //外部看门狗操作 }
for(i=0;i<650;i++) //出纸中间650步正常速度 { ExtWatchdog(); //外部看门狗操作 PAPER_OUT_CLK =1; //正脉冲 delay2us(Speed); //正常速度 PAPER_OUT_CLK =0; //负脉冲 delay2us(Speed); //正常速度 } for(i=0;i<200;i++) //出纸后200步慢停止 { ExtWatchdog(); //外部看门狗操作 PAPER_OUT_CLK =1; //正脉冲 delay2us(Speed+Speed*(i/20)); //缓慢停止,20个脉冲一档 PAPER_OUT_CLK =0; //负脉冲 delay2us(Speed+Speed*(i/20)); //缓慢停止,20个脉冲一档 } delay10ms(1); //停止10ms //送纸步进电机 PAPER_IN_EN=ENABLE; //使能送纸步进电机 PAPER_IN_CW=CW; //顺时针转 ExtWatchdog(); //外部看门狗操作
for(i=FixStep;i>0;i--) //两个电机同时慢启动 { ExtWatchdog(); //外部看门狗操作 PAPER_IN_CLK ^=1; //半脉冲 PAPER_OUT_CLK ^=1; //半脉冲 delay2us(Speed+i); //缓慢启动, if(PAPERNO) //有无纸传感器判断到无纸,无纸为低电平 { PAPER_IN_EN=1; //DISABLE; //关闭送纸步进电机 PAPER_OUT_EN=1; //DISABLE; //关闭出纸步进电机 send(PAPERNONE); //发送无纸字符 return; //返回 } } for(i=0;i<Step_Num;i++) { ExtWatchdog(); //外部看门狗操作 PAPER_IN_CLK ^=1; //半脉冲 PAPER_OUT_CLK ^=1; //半脉冲 delay2us(Speed); //正常速度 }
for(i=0;i<FixStep/2;i++) //慢停止 { ExtWatchdog(); //外部看门狗操作 PAPER_IN_CLK ^=1; //半脉冲 PAPER_OUT_CLK ^=1; //半脉冲 delay2us(Speed+i); //缓慢启动, } PAPER_OUT_CLK=1; //锁住电机 PAPER_IN_CLK=1; delay10ms(10); //停止100ms PAPER_IN_EN=1; //DISABLE; //关闭送纸步进电机 PAPER_OUT_EN=1; //DISABLE; //关闭出纸步进电机 }
看门狗 void ExtWatchdog(void) //外部看门狗监控子程序 { WDI=!WDI; //触发外部看门狗 if(!WDO) //外部看门狗输出低电平,程序跑飞,应复位 { send(RESET); //返回复位信息 WDTRST = 0x01e; WDTRST = 0x0aa; //软件复位 } }