📄 text1.c
字号:
#include "c8051F040.h"
#define uchar unsigned char
#define uint unsigned int
#define Motor_start 0x10 // 电机开启命令
#define Motor_stop 0x20 // 电机停止命令
#define Motor_control 0x30 // 接收数据的包头信号
#define Motor_turn 0x01 // 电机正转
#define Motor_Anti_turn 0x02 // 电机反转
bit Motor_Flag_turn=0; // 电机转动与停止转动的标志位
sbit Motor_CP =P4^1;
sbit Motor_DIR =P4^0;
sbit LED=P1^6; // 对LED操作的时候要先 SFRPAGE = CONFIG_PAGE;
xdata uchar uart0_data[5]={0xfe,0xcc,0x02,0x00,0x00};
uint pulse_num=0x0000; // 从串口接收到的脉冲数,脉冲数16进制高8位和低8位合并一个16位
uint Time0_num_LED=0; // 定时器中断次数,定时器每定时累积到1秒LED取反一次
// uart0_data[0]= TH0
// uart0_data[1]= TL0
// uart0_data[2]= 0x01正转 / 0x00反转
// uart0_data[3]= 脉冲数16进制高8位
// uart0_data[4]= 脉冲数16进制低8位
void port_init(); // 端口初始化函数
void os_init(); // 系统时钟初始化,选择外部晶体振荡器
void uart_init(); // 串口初始化,选择UART0
void time01_init(); // 定时器1初始化,作为UART0的波特率发生器,定时器0初始化
void delay(int tim)
{
int i,j;
for(i=0;i<tim;i++)
{
for(j=0;j<i;j++);
}
}
/*************************************************************************
*主函数
**************************************************************************/
void main()
{
WDTCN = 0xDE; // 关闭看门狗
WDTCN = 0xAD;
os_init(); // 晶振初始化
port_init(); // 端口初始化
uart_init(); // 串口初始化,选择UART0
time01_init(); // 定时器初始化,作为UART0的波特率发生器
SFRPAGE = CONFIG_PAGE;
IE = 0x92; // 开中断 bit7=EA 全局总中断
while(1)
{
if(Motor_Flag_turn==1)
{
SFRPAGE = TIMER01_PAGE;
TR0=1;
}
if(Motor_Flag_turn==0)
{
SFRPAGE = TIMER01_PAGE;
TR0=0;
SFRPAGE = CONFIG_PAGE;
LED=1;
}
if(pulse_num==0)
{
SFRPAGE = UART0_PAGE;
SBUF0=0x20;
Motor_Flag_turn=0;
}
if(pulse_num!=0)
{
Motor_Flag_turn=1;
SFRPAGE = UART0_PAGE;
SBUF0=uart0_data[2];
}
delay(1000);
}
}
// uart0_data[0]= TH0
// uart0_data[1]= TL0
// uart0_data[2]= 0x01正转 / 0x00反转
// uart0_data[3]= 脉冲数16进制高8位
// uart0_data[4]= 脉冲数16进制低8位
void time0 (void) interrupt 1
{
char i;
// TR0=0; // 先停止计数,来赋值
TH0=uart0_data[0];
TL0=uart0_data[1]; // 赋脉冲频率值
// TR0=1;
if(Time0_num_LED==0x07d0) // 2000*0.0005=1秒
{
SFRPAGE = CONFIG_PAGE;
Time0_num_LED=0;
LED=~LED;
}
else Time0_num_LED++;
SFRPAGE = TIMER01_PAGE;
if(pulse_num !=0)
{
i=uart0_data[2];
SFRPAGE = CONFIG_PAGE;
if(i==Motor_turn) // 电机正转
{
SFRPAGE = CONFIG_PAGE;
pulse_num--;
Motor_DIR=1;
Motor_CP=~Motor_CP ;
}
if(i==Motor_Anti_turn) // 电机反转
{
SFRPAGE = CONFIG_PAGE;
pulse_num--;
Motor_DIR=0;
Motor_CP=~Motor_CP ;
}
}
}
void UART0 (void) interrupt 4
{
uchar i,j;
uint temp=0x0000;
SFRPAGE = UART0_PAGE;
if(TI0==1) TI0=0;
if(RI0==1)
{
ET0=0; // 关定时器0中断 要置串口中断的优先级高于定时器中断
RI0=0;
i=SBUF0;
if(i==Motor_start) Motor_Flag_turn=1;
if(i==Motor_stop) Motor_Flag_turn=0;
if(i==Motor_control)
{
ES0=0;
SFRPAGE = UART0_PAGE;
for(j=0;j<5;j++)
{
while(RI0==0);
RI0=0;
uart0_data[j]=SBUF0;
}
ES0=1;
pulse_num=0x0000; // 从串口接收到的脉冲数,脉冲数16进制高8位和低8位合并一个16位
temp=uart0_data[3]; // 脉冲数16进制高8位
temp=temp<<8;;
pulse_num=temp;
temp=0x0000;
temp=uart0_data[4]; // 脉冲数16进制低8位
pulse_num=pulse_num|temp;
}
ET0=1; // 开定时器0中断
}
}
/*************************************************************************
*
*端口初始化函数
**************************************************************************/
void port_init()
{
SFRPAGE = CONFIG_PAGE;
// XBR0,XBR1,XBR2,XBR3为I/O端口寄存器
XBR0 = 0x04; //bit2=1,UART0 TX0配置到P0.0,RX0配置到P0.1
XBR2 = 0x40;
//bit6=1,Crossbar开启,用法:交叉开关配置时,为了防止配置过程中功能引脚
//产生干扰,在引脚配置过程中,将XBARE清0,配置结束后,再将其置1,使交叉开关生效
P0MDOUT=0X10;//P0口输出模式控制, 1:相应口为推挽输出模式
P1MDOUT=0xff;
P1MDIN=0xff;
P4MDOUT=0xff;
}
/*************************************************************************
*系统时钟初始化,选择外部晶体振荡器 外部22.1184M晶振
**************************************************************************/
void os_init()
{
int i = 0;
SFRPAGE = CONFIG_PAGE;
OSCXCN = 0x67; //外部22.1184M晶振
// 0110 0111,bit6-4:110为外部石英晶振模式,bit2-0:111为设置外部晶振驱动电流配置表,书150页
for (i = 0; i < 3000; i++); //等待外部晶振稳定
while ((OSCXCN & 0x80) == 0); //OSCXCN的bit7位为只读,外部晶振稳定运行时为1
CLKSEL = 0x01; //bit7-1保留,bit0为1时SYSCLK采用外部时钟
}
/*************************************************************************
*串口初始化,选择UART0
**************************************************************************/
void uart_init()
{
SFRPAGE = UART0_PAGE;
SCON0 = 0x50; //允许uart0接收
// 0101 0000,bit4=1为UART0接收开启,bit7-6:01为模式1,8位UART可变波特率异部传输
}
/*************************************************************************
*定时器初始化,作为UART0的波特率发生器
*************************************************************************/
void time01_init()
{
SFRPAGE = TIMER01_PAGE;
TMOD=TMOD&0x0F;
TMOD=TMOD|0x20; //bit5-4=T1M1-T1M0=10为T1模式为2,8位自动重载定时/计数器
CKCON=CKCON&0XEF; //先将bit4清0,然后再赋值
CKCON=CKCON|0X10; //bit4=1,T1时钟为系统时钟
TH1=0xb8; //0xb8=184: 22.1184 M /(256-184) * 1/32=9600
ET1=0; // 不允许T0中断
// TR1=1; 这里不能用这句,因为开了TR1,下面的定时器0的初始化对TMOD等操作无效了
// 所以要等定时器1和定时器0都初始化完了,再开TR1和TR0置为1
SFRPAGE = TIMER01_PAGE;
TMOD=TMOD&0xF0;
TMOD=TMOD|0x01; // 模式1(16位定时/计数器),仅受TR0控制
CKCON=CKCON&0xF7; // 先将bit3清0,然后再赋值
CKCON=CKCON|0x00; // bit3=0,T0时钟为系统时钟由SCA1~SCA0决定
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -