ST单片机C语言驱动电机程序

第一个正式的C语言单片机程序,用于驱动汽车大灯的电机

#include<St72F324.h>
#define VCC  4.9
typedef unsigned char  uchar ;
char state=0;
char en_drv=0;
char dir=0;
float target=0;
float location=0;
uchar turns=0; 
uchar cmd_word=0xdb;
void init()
{                      
 PADDR=0x18;
 PAOR=0x18;
 PADR=0x18;
 PCDDR=0x04;
 PCOR=0x07;
 PCDR=0x00; 
 PFDDR=0x02;
 PFOR=0x02;
 PFDR=0x00;
 SPICSR=0x01;
 SPICR=0x5f;
}
void init_adc(void)
{
   ADCCSR = 0x20;   /* ADC on ; AIN0 = analog input */
}
int adc_get(char channel)

 char i=0;  
 int sum=0;
 int aver=0;
  ADCCSR = 0x20 + channel;       /* select the channel to be converted */   
  for(i=0;i<16;i++)
  {
   while ((ADCCSR&0x80)==0);         /* wait for the end of conversion     */
   sum=sum+ADCDRH*4+(ADCDRL&3);
  } 
   aver=sum/16;
   return(aver);
}
void delay(uchar t)
{
 int i,j;
 for(i=0;i<t;i++)
  for( j=0;j<500;j++);
}
void deal_error()
{
 char state1=0;
 state1=state>>6;
 switch(state1)
 {
  case 0: PCDR=0x00;
          break;
  case 1: PCDR=0x00;
          break;
  case 2: PCDR=0x00;
          break;
  case 3:PCDR=0x00; 
         break;
 }
}
void write_cmd(uchar cmd)
{
  PADR=0x00;
  SPIDR=cmd;
  while((SPICSR&0x80)==0);
  state=SPIDR;
  PADR=0x08;
}
void drv_motor()
{
 uchar i=0;
 if(dir)
 {
  for(i=0;i<turns;i++)
  {
    switch(cmd_word)
    {
     case 0xdb: cmd_word=0xd3;
                break;
     case 0xd3: cmd_word=0xd2;
                break;
     case 0xd2: cmd_word=0xda;
                break;
     case 0xda: cmd_word=0xdb;
                break;
    }
    write_cmd(cmd_word);
    if((state&0xc0)!=0xc0)
      deal_error();
    delay(2);
  } 
 }
 else
 {
   for(i=0;i<turns;i++)
  {
    switch(cmd_word)
    {
     case 0xda: cmd_word=0xd2;
                break;
     case 0xd2: cmd_word=0xd3;
                break;
     case 0xd3: cmd_word=0xdb;
                break;
     case 0xdb: cmd_word=0xda;
                break;
    }
    write_cmd(cmd_word);
    if((state&0xc0)!=0xc0)
      deal_error();
    delay(2);
  } 
 }
 en_drv=0;
 write_cmd(cmd_word|0xf6);  //turn off motor
}
/*some case must be noted in main function:
1.delay(T) func parameter T can be changed
  by user's need.usally it is commend using 2;
2.The diffrence between variable location and
  target can be by user's need, but you should
  use 0.021*N(N is integer);
*/
void main()
{
 char i=0; 
 int sen0=0,sen1=0;    
 init();
 init_adc();
 while(1)
 {
  sen0=adc_get(0);
  sen1=adc_get(1);
  target=(sen1-sen0)*VCC/1023;
  if(location-target>0.063)        //0.0625 v
     { dir=0;
     turns=48*(location-target);   //转动格适?  48=120/2.5
     en_drv=1;
   }
  if(target-location>0.063)         //0.042
   {
    dir=1;
    turns=48*(target-location);
    en_drv=1;
   }
  if(en_drv)
   {
    drv_motor();
    location=target;
   }
 } 
}

  //step: 1.build 2.debug 3. program 
  //4.select the erase and Program Option Bytes
  //5.download

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include //器件库 #include //延时函数库 #include //标准I/O函数库 #include //标准函数库 unsigned char m0,m1,m2; unsigned char s,s1; // 单片机定时器0溢出中断服务程序段 // 产生伺服电机动作所需要的脉宽 interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0=0xBA; if(s<m0)PORTA.0=1;else PORTA.0=0; if(s<m1)PORTA.1=1;else PORTA.1=0; if(s127) { s=0; s1=0; TCCR0=0x00; TCCR1B=0x02; TCNT1H=0xff; TCNT1L=0x59; } } // 单片机定时器1溢出中断服务程序段 // 产生0.5ms的开始脉宽和5ms以上的间隔脉宽 interrupt [TIM1_OVF] void timer1_ovf_isr(void) { #asm("wdr"); //喂狗 TCNT1H=0xff; TCNT1L=0x59; s1++; if(s170) { TCCR1B=0x00;TCCR0=0x01;s1=0;TCNT0=0xBA;} } } void main(void) { unsigned char i,j,count=0; unsigned char c[3]; unsigned int k; // 设置A口为输出状态,并且初始值为低电平 PORTA=0x00; DDRA=0xFF; // 设置B、C、D、E口为高阻输入状态,在该程序中不使用 PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0x00; PORTE=0x00; DDRE=0x00; //设置定时器0的时钟来源为系统晶体 //设置计数周期为8000KHZ,清空计数寄存器 TCCR0=0x00; TCNT0=0x00; OCR0=0x00; //设置定时器1的时钟来源为系统晶体 //设置计数周期为1000KHZ,清空计数寄存器 TCCR1A=0x00; TCCR1B=0x02; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; //使能定时器 TIMSK=0x82; // 串口模数据:8个数据位,1个停止位,无奇偶效验 // 串口使能:发送、接收 // 串口模式:异步 // 串口速率:9600 UCSRA=0x02; UCSRB=0x18; UCSRC=0x86; UBRRH=0x00; UBRRL=0x34; //设置模拟比较器 ACSR=0x80; //使能看门狗,设置喂狗周期为 时钟/2048 WDTCR=0x1F; WDTCR=0x0F; // 打开总中断 #asm("sei") delay_ms(500); putchar(0x0d); putchar(0x0a); putsf("***********************************\r"); putsf("* 3路舵机驱动程序 *\r"); putsf("* 顺德职业技术学院 机电工程系 *\r"); putsf("* 罗建章 *\r"); putsf("***********************************\r"); while (1) { count=0; putsf("输入舵机编号(1~3):"); putchar(0x0d); n1:i=getchar(); if((i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值