- #include<STC12C5A60S2.h>
- //单片机头文件,储存一些殊寄存器的地址声明
- #include<intrins.h>
- //intrins头文件储存51编程中需要使用到空指令_nop_()、字符循环移位指令_crol_等
- #include <stdio.h>
- //stdio : "standard input & output"(标准输入输出),C/C++头文件,把多个编译单元(.c或者.cpp文件)公用的内容,单独放在一个文件里减少整体代码尺寸
- #define usint unsigned short int //符号短整型
- #define uchar unsigned char //无符号字符型
- #define uint unsigned int //无符号整型
- #define VALID 0 //0
- #define INVALID 1 //1
- #define LCD_data P0 //LCD数据端口P0
- sbit LCD_RS = P2^7; //LCD命令和数据控制位,1:写数据位,0:写命令
- sbit LCD_RW = P2^6; //LCD读写控制位
- sbit LCD_EN = P2^5; //LCD使能位
- sbit IN1 = P2^0; //电机
- sbit IN2 = P2^1;
- sbit ENA = P2^3;
- uchar code title2[] = {"电机转速:"};
- uchar code ascii[] =
- {0x31,0x32,0x33,0x41,0x34,0x35,0x36,0x42,0x37,0x38,0x39,0x43,0x2A,0x30,0x23,0x44}; //数字和常用字符的ascii码
- uint n = 0; //T0定时中断响应次数
- uint n_pwm = 0; //用于调节pwm占空比
- uint c = 0; //外部计数中断响应次数
- uint flag_T0 = 0; //定时器T0溢出flag
- uchar th = 0; //脉冲计数计算时的临时变量高位
- uchar tl = 0; //……………………………………………低位
- uint num_pulse; //脉冲个数
- void delay_1ms(uint z){ //延时函数1ms
- uint x,y;
- for(x = z; x > 0; x--)
- for(y = 920; y > 0; y--);
- }
- void write_cmd(uchar cmd){ //LCD写命令函数
- LCD_RS = 0;
- LCD_RW = 0;
- LCD_EN = 0;
- P0 = cmd;
- delay_1ms(6);
- LCD_EN = 1;
- delay_1ms(6);
- LCD_EN = 0;
- }
- void write_dat(uchar dat){ //LCD写数据函数
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_EN = 0;
- P0 = dat;
- delay_1ms(5);
- LCD_EN = 1;
- delay_1ms(5);
- LCD_EN = 0;
- }
- void lcd_pos(uchar X,uchar Y){ //X表示LCD的行数,Y表示LCD的列数
- uchar pos;
- if(X == 0){
- X = 0x80;
- }
- else if(X == 1){
- X = 0x90;
- }
- else if(X == 2){
- X = 0x88;
- }
- else if (X == 3){
- X = 0x98;
- }
- pos = X+Y ;
- write_cmd(pos); //显示地址
- }
- void lcd_init(){
- uchar i = 0;
- write_cmd(0x30); //基本指令操作
- delay_1ms(5);
- write_cmd(0x0C); //显示开,关光标
- delay_1ms(5);
- write_cmd(0x01); //清除LCD的显示内容
- delay_1ms(5);
- lcd_pos(0,0); //将LCD光标定位到第一行第一列
- }
- void pulse_dispaly(uint fe) //显示脉冲个数
- {
- uchar i = 0;
- uchar f[7];
- for(i = 0; i < 7; i++)
- f[i] = '0';
- f[0] = ((fe)/100000) +0x30;//十万位的数字
- f[1] = ((fe)%100000)/10000 +0x30;//万位的数字
- f[2] = ((fe)%10000)/1000 +0x30;//千位的数字
- f[3] = ((fe)%1000 )/100 +0x30;//百位的数字
- f[4] = ((fe)%100 )/10 +0x30;//十位的数字
- f[5] = ((fe)%10 ) +0x30;//个位的数字
- f[6] = '\0';
- i = 0;
- lcd_pos(1,5); //将光标定位到第2行第6列开始显示
- while(f[i] != '\0'){
- write_dat(f[i]);
- i++;
- }
- }
- void display_text(int pos, uchar *text){ //显示一段字text、pos设置在第几行开头显示
- uchar j;
- lcd_pos(pos,0);
- while(text[j]!='\0'){
- write_dat(text[j]);
- j++;
- }
- j=0;
- }
- void INIT(){ //初始化函数
- TMOD = 0X51; //定时器初始化0101_0001
- TH0 = (65536-922)/256; //定时器初值(1ms),0.001s/(1.085*10^(-6))s=922
- TL0 = (65536-922)%256;
- TH1 = 0X00; //计数器初值
- TL1 = 0x00;
- ET0 = 1; //允许中断T0
- ET1 = 1;
- EA = 1; //总中断开放
- TR0 = 1; //启动T0
- TR1 = 1; //启动T1
- IN2 = 0; //电机初始化
- IN1 = 1;
- ENA = 0;
- }
- void main(){
- uchar i;
- INIT();
- lcd_init(); //LCD初始函数
- display_text(1, title2); //在第2行开头显示 "电机转速:"
- while(1){
- if (flag_T0 == 1){ //1s
- /*脉冲计数(电机转速通过脉冲个数的方式输出)*/
- th = TH1; //用临时变量读取计数器数值
- tl = TL1;
- num_pulse = th*256 + tl; //计数器16进制转10进制
- TH1 = 0X00; //重新赋计数器的值
- TL1 = 0x00;
- pulse_dispaly(num_pulse); //循环调用显示函数
- th = 0;
- tl = 0;
- /*脉冲计数*/
- flag_T0 = 0;
- }
- }
- }
- void interrupt_Timer0() interrupt 1 { //定时器中断(1ms)
- TR0 = 0;
- TH0 = (65536-922)/256; //重新赋初值
- TL0 = (65536-922)%256;
- n++;
- n_pwm++; //一个pwm脉冲周期为10ms,速度10档可调
- ENA = 1;
- if (n_pwm > 10) //超过一个pwm周期
- n_pwm = 1;
- if (n_pwm <= 5) //占空比50%
- IN1 = 1; //pwm高电平
- else
- IN1 = 0; //pwm低电平
-
- if(n == 1000){ //计满1s
- flag_T0 = 1;
- n = 0;
- }
- TR0 = 1;
- }
- void interrupt_Timer1() interrupt 3 { //计数器中断
- TR1 = 0;
- TH1 = 0x00; //重新赋值
- TL1 = 0x00;
- TR1 = 1;
- }
复制代码
|