分类目录归档:单片机

STM8L用内部参考电压做AD转换基准电压

STM8L系列芯片一般采用电池供电,当电池使用一段时间后,电池电压下降,如果使用电池电压作为AD转换参考电压,会导致AD采样失真。STM8L内部有一个参考电压,电压为1.225V,使用内部参考电压做基准,可以解决这个问题。

以stm8l052为例,

AD初始化:

clip_image002

采样内部参考电压,以单片机供电电压为基准

clip_image004

采样NTC热敏电阻电压,以单片机供电电压为基准,在AD采样4通道。

clip_image006

#define VREF 1.225L

根据内部参考电压计算NTC电阻电压,因为内部参考电压固定,而且和检测NTC电阻电压AD都使用单片机供电电压同一个参考源,所以内部参考电压AD值和NTC电阻电压AD值成比例关系。

NtcAdValue = GetNtcAd();

VNtc = ((float)NtcAdValue*VREF)/(float)VrefintAdValue;

也可以根据内部参考电压计算当前单片机的实际供电电压

VrefintAdValue = GetVrefintAd();

VddValue = (4096*VREF)/(float)VrefintAdValue;

当NTC电阻和一个430K电阻串联分压时,根据当前单片机的实际供电电压就可以计算出NTC电阻当前的阻值了

Rs = (430*VNtc)/(VddValue-VNtc);

无刷直流电机正反转过零点换相

无刷无感直流电机换向时一般采用反电动势过零点的办法,ABC三相端电压经低通滤波器后,求和得出模拟中性点,滤波后的端电压再与模拟中性点电压比较得到过零点。过零点检测电路如下,R72,R73,R74分别接ABC三相端电压。

clip_image002

三相电机一般采用两相导通六步换相的控制方法,正转和反转是相对的,假如正转的通电顺序是A+B-,A+C-,B+C-,B+A-,C+A-,C+B-,

那么反转的通电顺序应该是

C+B-,C+A-, B+A-, B+C-, A+C-, A+B-,

clip_image004

clip_image006

上图是正转时各绕组的电流和感应电动势。 继续阅读

PID算法控制马达转速

PID算法听起来高大上,理解后实际上是很简单的,实现代码也很小。

PID控制是将实际值与目标值的偏差的比例(P),积分(I),微分(D)的线性组合作为控制量,控制被控对象。

PID控制器各个校正环节的作用如下:

1、 比例环节:用来控制当前,即时成比例地反映偏差信号,偏差一旦出现,比例环节立即产生作用来减小偏差。

2、 积分环节:用来控制过去,主要作用是消除静差,积分常数Ti越小,积分作用越强,Ti越大,积分作用越弱。

3、 微分环节:用来控制将来,能对偏差的变化做出反应,在偏差变化太大之前加入控制信号。微分常数越大,做出的反应越快,从而减小系统调节时间。

一、模拟PID控制原理:

clip_image002

其中,r(t)是给定值,y(t)是系统的实际输出值,给定值与实际输出值的差值e(t)=r(t)-y(t).e(t)作为PID控制器的输入,u(t)作为PID控制器的输出,也是被控对象的输入。所以,模拟PID的控制规律为:

clip_image004

其中,Kp为控制器的比例系数;Ti为控制器的积分时间常数;Td为控制器的微分时间常数。

(1)比例部分:Kp*e(t)

在模拟PID控制器中,比例环节的作用是对偏差瞬间作出反应。偏差一旦产生,控制器立即产生控制作用,使控制量向减小偏差的方向变化。控制作用的强弱取决于比例系数Kp。Kp越大,控制作用越强,则过渡过程越快,控制过程的静态偏差也就越小。但是Kp越大,也越容易产生振荡,破坏系统的稳定性。

(2)积分部分
从积分的数学表达式可知:只要存在偏差,则它的控制作用就不断增加。只有在偏差值为零时,它的积分才是一个常数。控制作用才是一个不会增加的常数。可见,积分部分可以消除系统的偏差。
积分环节虽然会消除静态误差,但是也会降低系统的响应速度,增加系统的超调量。积分时间常数越大,积分的积累越弱。这时,系统在过渡时不会产生振荡。但是,增大积分时间常数会减慢静态误差的消除过程,消除偏差所需的时间也较长,但可以减少超调量,提高系统的稳定性。
当积分时间常数较小时,则积分的作用较强。这时系统过渡时间中有可能产生振荡,不过消除偏差所需的时间较短。所以必须根据实际控制的具体要求来确定积分时间常数。
积分系数(积分增益)是指:Ki=K_p/T_i 。
(3)微分部分:Kp*Td*(de(t))/dt
控制系统除了期望消除静态误差外,还要求加快调节过程。在偏差出现的瞬间,或在偏差变化的瞬间,不但要对偏差量做出立即响应(比例环节的作用),而且要根据偏差的变化趋势预先给出适当的纠正。为了实现这一作用,可以在PI控制器的基础上加入微分环节,形成PID控制器。
微分环节的作用是阻止偏差的变化。它根据偏差的变化趋势(变化速度)进行控制。偏差变化的越快,微分控制器的输出就越大,并能在偏差值变大之前进行修正。微分作用的引入,有助于减小超调量、克服振荡,使系统趋于稳定。特别对高阶系统有利,它加快了系统的跟踪速度。但微分的作用对输入信号的噪声很敏感。对那些噪声较大的系统一般不用微分,或在微分起作用之前先对输入信号进行滤波。
微分部分的作用由微分时间常数决定。微分时间常数越大时,则它抑制偏差变化的作用越强;微分时间常数越小时,则它反抗偏差变化的作用越弱。微分部分显然对系统稳定有很大的作用。适当地选择微分时间常数,可以使微分作用达到最优。
微分系数是指:Kd= Kp*Td。

继续阅读

CH372实现HID键盘功能

有些IC发卡器在刷卡时,卡号可以填写在文档光标处。这种产品很多年前就有了,最近刚好有客户有这方面需求,用CH372做了一款HID键盘类型的发卡器。

一款HID设备包括设备描述符,配置描述符,接口描述符,端点描述符,HID描述符,HID描述符包括报告描述符,另外还有字符串描述符,语言描述符。对HID键盘设备,用BusHound抓包时没看到PC请求语言描述符和字符串描述符。

设备描述符:

image

image

配置描述符:

image

image

image

image

报告描述符: 继续阅读

STM8S定时器1实现PWM功能

TIM1由一个16位自动装载计数器组成,由一个可编程的预分频器驱动。可用来输出PWM波形。

TIM1的PWM模式可以产生一个由TIM1_ARR寄存器确定频率,由TIM1_CCRi确定占空比的信号。

TIM1由4个独立的捕获/比较通道,其中TIM1_CH1,TIM1_CH2,TIM1_CH3由都对应的互补输出引脚TIM1_CH1N,TIM1_CH2N,TIM1_CH3N.TIM_CH4没有互补输出引脚。TIM1_CH1,TIM1_CH2,TIM1_CH3,TIM1_CH1N,TIM1_CH2N,TIM1_CH3N常用于直流无刷电机的六步PWM控制。

以下是设置TIM1_CH1,TIM1_CH2,TIM1_CH3引脚输出30%占空比的例子,TIM1_CH1N,TIM1_CH2N,TIM1_CH3N不输出。PWM信号频率为16K。

clip_image002[4]

需要配置STM8S的选项设置管脚的功能,选择PWM1模式

clip_image004[4]

注意这里的有效电平要和TIM1_CCER1,TIM1_CCER2里的CCiP对应起来

clip_image006[4]

image

485通讯调试总结

485通讯是常见的应用,实现通讯很简单,但是要保证通讯的稳定,有一些细节需要注意。

485通讯一般采用一主多从的方式,主机轮询多个从机。从机接收到主机的数据后,根据地址判断是否要接收数据,地址匹配,从机接收数据,处理完后发送应答数据给主机。地址不匹配,从机丢掉数据。

通讯协议推荐采用ASCII码,协议格式如下:

 

image

采用ASCII码的好处是单片机的串口接收程序容易判断整帧数据的头码和尾码。如果采用16进制的方式,发送的数据内容可能包括头码和尾码的字符,导致接收出错。ASCII码方式则避免了这种问题。

不管是主机还是从机,485芯片只是在发送数据时处于发送模式,发送完数据后就要切换为接收模式。从接收模式切换到发送模式时,至少需延时1ms等待485芯片状态稳定再发送数据。发送完数据后也至少需要延时1ms等待数据完全发送后再切换到接收模式。

485是半双工通讯方式,也就是说同一时刻只能发送或接收。从机收到主机的轮询数据后,建议从机关闭串口接收中断,发送完数据再打开串口接收中断。从机会接收到两种数据,一个是主机的轮询数据,一个是其它从机返回给主机的数据,从机的串口中断接收程序应注意区分。

当主机发送轮询命令给一个从机后,等待一段时间,再发送轮询命令给另一个从机,这时第一个从机返回数据给主机,这个时候就会发生数据碰撞,导致主机接收的数据错误,从机接收的数据也错误。这种情况在半双工通讯的情况下很难避免。只能调整主机发送轮询命令的间隔时间来减少这种情况的发生。

根据年月日计算星期

在门禁系统中要用到星期,但是在设置时间的时候,一般只设置年月日时分秒,不会去设置星期,那么如何根据年月日来得到星期?

计算星期可以用蔡勒(Zeller)公式(只适合于1582年10月15日之后的情形):

     w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

公式中的符号含义如下:
     c:世纪(年的高两位数);
     y:年(年的低两位数);
     m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月
来计算,比如2005年1月1日要看作2004年的13月1日来计算);
     d:日;
     []代表取整,即只要整数部分。
     w:星期;w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,
        5-星期五,6-星期六

以2005年2月14日为例:c=20,y=4,m=14,d=14
     w = 4 + [4/4] + [20/4] – 2*20 + [26*(14+1)/10] + 14 – 1
       = 4 + 1     + 5      – 40   + 39             + 14 – 1
       = 22 (除以7余1)
所以2005年2月14日是星期一。

继续阅读

计算时间差(精确到分钟)

用2个BCD码数组存储进场时间和出场时间:

unsigned char idata in[5] = {0x10,0x07,0x14,0x20,0x15};//2010年7月14日20时15分

unsigned char idata out[5] = {0x10,0x07,0x15,0x08,0x14};//2010年7月15日8时14分

unsigned char idata in_time[5];//存进场时间的16进制数

unsigned char idata out_time[5];//存出场时间的16进制数

首先把这两个数组的BCD码转成HEX码

转换算法:比如把BCD码12h转换成16进制,用12h-6,得到0ch,就是对应的16进制数。十位为n,就用BCD码-n*6,如23h,23h-2*6=17h,17h就是BCD码23

/*

把一个BCD码数组转换成16进制数组

*/

void Bcd_to_Hex(unsigned char *bcd_array,unsigned char *hex_array,unsigned char n)

{

unsigned char i = 0;

unsigned char temp;

for(i = 0;i < n;i++)

{

temp = (bcd_array[i] & 0xf0) >> 4;

hex_array[i] = bcd_array[i];

while(temp–)

{

hex_array[i] = hex_array[i] – 0x06;

}

}

}

然后调用函数difftime(unsigned char *in_time,unsigned char *out_time)得到进出时间相隔多少分钟

/*

计算车在场内停留的时间,单位分钟

能计算的最长停留时间是65535/(24*60)=45.5天

*/

继续阅读

串口扩展芯片VK3214使用总结

最近一个项目需要用到3个串口,但是用的MCU只有2个串口,选择多串口的单片机成本太高,最后打算用串口扩展芯片VK3214扩展2个串口。

VK3214可以用单片机的一个串口扩展出4个子串口,每个子串口都可以单独设置波特率。

脚位图如下:

clip_image002

MRX,MTX分别接单片机一个串口的TX,RX。RXn,TXn 为扩展的4个子串口。

每个子串口有16字节的发送FIFO,16字节的接收FIFO。当发送FIFO触发点中断使能时,发送FIFO中的数据小于设定的触发点时产生相应的中断。当接收FIFO触发点中断使能时,接收FIFO中的数据大于设定的触发点时产生相应的中断。

中断脚IRQ低电平有效,注意不是下降沿有效。IRQ接单片机的中断脚,中断脚接单片机的外部中断脚INT,INT要设置为低电平有效。因为是低电平有效,在进入中断程序后,要禁止外部中断,中断处理完后再开外部中断。

继续阅读

ATMEGA128看门狗设置

ATMEGA128设置看门狗时,按文档写的流程

WDTCR = 0x18;

WDTCR = 0x0f;

调试程序时,直接运行,WDTCR的预分频值7写不进去,一直是默认的0,14ms就复位。单步运行预分频值能写进去,是0x0f。

后来我调用wdt.h库文件的函数

cli();

wdt_disable();

wdt_enable(WDTO_2S);

直接运行可以写预分频值,大概2S,看门狗复位。

在主程序中调用wdt_reset();清看门狗。

第 1 页,共 2 页12