#include <c8051f330.h>
#define uint unsigned int
#define uchar unsigned char
#define T0_1ms (65536 - 25 ) //0.1ms 需要再确定初值大小
sbit DIR = P1^3; //485口
char reciev[3], rec_num; //主机发送三个字符的信息
uchar k;
sbit PWM1 = P0^1;
sbit AD = P0^0;
void init_uart0() //串口初始化
{
REN0 = 1;
ES0 = 1;
EA = 1;
IP |= 0x10;
}
void init_timer() //定时器初始化
{
TMOD |= 0x01;
TH0 = T0_1ms/256;
TL0 = T0_1ms%256;
ET0 = 1;
TR0 = 1;
TMOD |= 0x20;
TH1 = 0x96;
TL1 = 0x96;
ET1 = 1;
TR1 = 1;
}
void ms_delay(unsigned int t) //延时函数
{
unsigned int i;
for (t;t > 0; t-- )
for (i = 28;i > 0; i-- )
;
}
void PORT_Init (void)
{
P0MDIN |= 0x03; // P0.0 P0.1数字输出
P0MDOUT = 0x03; // P0.0 P0.1 is push-pull
XBR0 = 0x01; // 使能UARTP0.4(TX)P0.5(RX)
XBR1 = 0x40; // 使能交叉开关,弱上拉
}
void send(char c) //发送数据函数
{
DIR == 1;
SBUF0 = c;
while(!TI0);
}
void jiman20() //PWM波
{
static uchar flag = 0,j = 5; //flag当做PWM高电平变宽/变窄的标志;
//j表示高电平持续的时间;k表示总时间.因为重复调用该函数
if(k == 200) //第一步:判断计时满20ms.
{
k = 0; //k归零
if(flag == 0) //标志为0时,高电平标志增加
j++;
else //标志为1时,高电平标志减小
j--;
if(j >= 25) //当j=25时,高电平持续时间为2.5ms,此时角度为180.
flag = 1; //必须改变宽/窄标志。
if(j <= 5) //当j=5时,高电平持续时间为0.5ms,此时角度为0.
flag = 0; //必须改变宽/窄标志。
}
if(k < j) //第二步:在20ms判断结束的基础上,输出PWM
PWM1 = 1; //因为每20ms,k就归0.所以能通过判断k<j,输出高电平
else PWM1 = 0;
}
void Timer0_interrupt() interrupt 1 //定时器中断
{
TF0 = 0;
TH0 = T0_1ms/256;
TL0 = T0_1ms%256;
k++;
TF0 = 1;
}
void UART_interrupt() interrupt 4 //串口中断
{
char checkXOR;
if(RI0)
{
RI0=0;
reciev[rec_num] = SBUF0;
rec_num ++;
if ((rec_num ==3) && (reciev[0] == 0x0f) ) //检验与或关系
{
checkXOR = reciev[0] ^ reciev[1];
if (checkXOR == reciev[2])
{
send(0xf0);
send(0x01);
send(0xf1);
switch(reciev[1])
{
case 0x01:
TR0 = 1;
rec_num = 0;
break;
case 0x02:
TR0 = 0;
rec_num = 0;
break;
default:
reciev[0] = reciev[1];
reciev[1] = reciev[2];
rec_num --;
break;
}
}
}
}
if(TI0)
{
TI0 = 0;
}
}
void main()
{
uint p = 60000;
init_uart0();
init_timer();
AD = 1;
while(p--) //一开机就让舵机有一个转动
{
jiman20();
}
ms_delay(500);
DIR == 0;
while(1)
{
jiman20();
}
}
|