打印
[经验分享]

ATmega48上拉式磁悬浮

[复制链接]
2598|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
panxiaoyi|  楼主 | 2021-2-2 01:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*****************************************************
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);
  };
}

使用特权

评论回复
沙发
panxiaoyi|  楼主 | 2021-2-2 01:26 | 只看该作者


/*
adc.h内容 / 请修改ADC的输入通道 !!!  
   
被测电压 V = ADC*AREF/bit 由于AREF/bit是固定的,所以可以把它变为一个系数
被测电压 V = ADC * 系数
如果AREF=5000mV,ADC结果是8bit 则 系数 = 5000/255  = 98/5 请注意数据计算不能溢出
*/


void adc_start(unsigned char input_io) //ADC初始化并启动某通道的ADC/ADC转化需要一定的时间
{
  PORTC &= 0b00001111;                 //ADC输入通道
  DDRC  &= 0b00001111;
  DIDR0 |= 0b11110000;                 //引脚7654禁止数字输入
  ADMUX  = 0b01100000+input_io;        //参考电压=AVCC/结果左对齐8bit/通道ADC_IO=0-7
  ADCSRA = 0b10010011;                 //ADC使能/8MHz/32=250K时钟(50-200K)
  ADCSRA|=64;                          //启动ADC转换
}


unsigned char adc_read(void)           //读取ADC原始数据/8位/每次切换不同通道后,第一次结果不太准确建议舍弃
{
  unsigned char adc_data;
  while((ADCSRA&16)==0);               //等待转换结束
  adc_data=ADCH;                       //读取数据
  ADCSRA|=16;                          //清除转换结束标记   
  return adc_data;
}   

使用特权

评论回复
板凳
panxiaoyi|  楼主 | 2021-2-2 01:29 | 只看该作者
代码

M48上拉式磁悬浮.rar

51.48 KB

使用特权

评论回复
地板
panxiaoyi|  楼主 | 2021-2-2 01:30 | 只看该作者
顺便发个ATtiny13的也是一样的磁悬浮代码

T13磁悬浮.rar

95.83 KB

使用特权

评论回复
5
panxiaoyi|  楼主 | 2021-2-2 14:48 | 只看该作者
改进了一下
/*****************************************************
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)
  {                                                                                

  };
}


使用特权

评论回复
6
panxiaoyi|  楼主 | 2021-2-2 14:50 | 只看该作者
改进后的代码

ATtiny13上拉式磁悬浮.rar

99.83 KB

使用特权

评论回复
7
qq9472044| | 2021-9-9 17:19 | 只看该作者
楼主,可以留下联系方式吗?交流交流

使用特权

评论回复
8
chenqianqian| | 2021-9-10 18:21 | 只看该作者
下载看看,谢谢分享。

使用特权

评论回复
9
panxiaoyi|  楼主 | 2021-9-11 10:38 | 只看该作者
qq9472044 发表于 2021-9-9 17:19
楼主,可以留下联系方式吗?交流交流

这个帖子是发错位置的,可以看下面的链接,有图片,68354248@qq.com

https://bbs.21ic.com/forum.php?mod=viewthread&tid=3069754&highlight=%E7%A3%81%E6%82%AC%E6%B5%AE

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

393

帖子

2

粉丝