/*****************************************************
panxiaoyi
CodeWizardAVR
Chip type : ATtiny13
Clock frequency : 9.6 MHz
上拉式磁悬浮
本程序与电磁力学和惯性和重力加速度有关
电磁铁在上,螺丝钉在下,螺丝钉的底部有强磁小磁铁吸附
网购的电磁铁铁心直径8MM,高15MM,6欧姆,580匝
主供电18V/2A,强磁铁直径10MM,高5MM,空心。螺丝钉长30MM,直径5MM
单片机OC0A(PD6)直接驱动MOS管K2749,无保护二极管,无续流二极管
线性霍尔元件49E贴于磁铁底部中央,无磁时输出VCC/2电压,有南北磁时电压变大或者变小
霍尔元件有印字面朝向大地,背面贴于电磁铁,调换电磁铁接线,使线圈通电时E49输出电压变小
电磁铁由连续的PWM驱动,在每个方波的下降沿开始计数延时,然后检测49E输出电压
方波出现下降沿后延时是为了等待剩磁消失,以免由此引起的测量误差
电磁铁没有续流二极管时,剩磁消失快,有续流二级管时,剩磁消失慢会影响霍尔检测
PWM频率不宜太高,高电平最大占空比不宜太大,这样做的目的是保证检测49E时没有剩磁干扰
也保证在模数转换完成之前,下一个方波还没有出现
特别注意:
由于上述多种作用力的存在,悬浮物上升时和下降时应该分别处理,使用PID算法也要分开处理
当悬浮物上升时,即使它没有上升到预期点,也应该减少磁电力
当悬浮物下降时,即使它没有下降到预期点,也应该增大磁电力
使用8位ADC和8位PWM即可
*****************************************************/
#include <tiny13.h>
#define SET 80 //期望值
#define E49L 45 //完全吸合时测量霍尔元件E49的值
unsigned int adc_new, adc_old, pwm ;
interrupt [TIM0_COMPB] void timer0_ovf_isr(void) //在PWM低电平期间检测霍尔数据
{
adc_old=adc_new; //更新旧数据
ADMUX=32+2; //参考电压VCC/结果左对齐/通道ADC_IO=0-3
ADCSRA=0b11000111; //ADC使能/启动ADC转换/128分频
while((ADCSRA&16)==0); //等待转换结束
adc_new=ADCH; //读取数据
ADCSRA|=16; //清除转换结束标记
if(adc_old<adc_new) //下降时
{
if(adc_new<SET) pwm=(adc_new-E49L)*4; //悬浮物下降到期望值之前
else pwm=(adc_new-E49L)*5; //悬浮物下降到期望值之后
}
if(adc_old>adc_new) //上升时
{
if(adc_new<SET) pwm=(adc_new-E49L)*2; //悬浮物上升到期望值之后
else pwm=(adc_new-E49L)*3; //悬浮物上升到期望值之前
}
if(adc_new<110)DDRB.0=1; else DDRB.0=0; //无磁时保护
if(adc_old<E49L && adc_new<E49L) pwm=0; //防吸死保护
if(pwm>150) pwm=150; //占空比不能太多
OCR0A=pwm; //更新pwm占空比
OCR0B=pwm+90; //在PWM输出低电平后延时中断以确保没有剩磁
}
void main(void)
{
TCCR0A=0b10000011; //OCR0A快速PWM
TCCR0B=0b00000011; //7.3728M除以256计数再除以64分频=590Hz
TIMSK0=0b00001000; //OCR0B比较匹配中断使能
SREG|=128; //全局中断使能
while (1)
{
};
}
|