第一个正式的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