/*****************************************************
CodeWizardAVR
Chip type : ATmega48
Clock frequency : 9.6 MHz
上拉式磁悬浮
本程序与电磁力学和惯性和重力加速度有关
电磁铁在上,螺丝钉在下,螺丝钉的底部有强磁小磁铁吸附
网购的电磁铁铁心直径8MM,高15MM,6欧姆,580匝
主供电18V/2A,强磁铁直径10MM,高5MM,空心。螺丝钉长30MM,直径5MM
单片机OC0A(PD6)直接驱动MOS管K2749,无保护二极管,无续流二极管
线性霍尔元件49E贴于磁铁底部中央,无磁时输出VCC/2电压,有南北磁时电压变大或者变小
电磁铁由连续的PWM驱动,在每个方波的下降沿开始计数延时,然后检测49E输出电压
方波出现下降沿后延时是为了等待剩磁消失,以免由此引起的测量误差
电磁铁没有续流二极管时,剩磁消失快,有续流二级管时,剩磁消失慢
PWM频率不宜太高,高电平最大占空比不宜太大,这样做的目的是保证检测49E时没有剩磁干扰
也保证在模数转换完成之前,下一个方波还没有出现
特别注意:
由于上述多种作用力的存在,悬浮物上升时和下降时应该分别处理,使用PID算法也要分开处理
当悬浮物上升时,即使它没有上升到预期点,也应该减少磁电力
当悬浮物下降时,即使它没有下降到预期点,也应该增大磁电力
使用8位ADC和8位PWM即可
*****************************************************/
#include <mega48.h>
#include <adc.h>
#include <nokia3310.h>
unsigned char adc_new, adc_old, pwm ;
interrupt [TIM0_COMPB] void timer0_ovf_isr(void) //在PWM低电平期间检测霍尔数据
{
adc_old=adc_new; //更新旧数据
adc_start(5); //启动某通道ADC/参考电压5V/8bit
adc_new=adc_read(); //等待和读结果/电压=ADC_DATA*98/5
if(adc_old<adc_new) pwm=(adc_new-50)*4; //下降时加大占空比,幅度要比上升大
if(adc_old>adc_new) pwm=(adc_new-55)*2; //上升时减少占空比。此数据要反复调试
if(adc_new<110)DDRD.6=1; else DDRD.6=0; //无磁时保护
if(adc_old<60 && adc_new<60) 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分频=450Hz
lcd_init(); lcd_cls(); //LCD初始化
TIMSK0 =0b00000100; //OCR0B比较匹配中断使能
SREG|=128; //全局中断使能
while (1)
{
lcd_gotoxy(20,2); //LCD显示(可删除该部分代码)
lcd_putbyte(OCR0A);
lcd_putchar(' ');
lcd_putbyte(adc_new);
lcd_gotoxy(8,4);
lcd_putsf("PAN XIAO YI",11);
};
}
|