找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 45865|回复: 17
打印 上一主题 下一主题
收起左侧

CT107D蓝桥杯单片机编程笔记

  [复制链接]
跳转到指定楼层
楼主
ID:86860 发表于 2015-7-26 00:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、              IO口编程

IO编程,该开发板使用了573锁存器,通过P2口的5,6,7位连接3-8译码器,扩展出了8个口,其中4个口分别连接4个573锁存器,这里以LED的锁存器来举例:
原理图573:
分析代码:
P2=((P2&0x1f)|0x80);
其中0x1f=0001 1111,P2与0x1f进行与运算,高三位清零,其余位保持原来状态,不改变,即把控制3-8译码器的高三位留出来:
接着再或上0x80;容易发现0x80=1000 0000;或运算,与1或结果为1,与0或结果不变,所以或上0x80只需看P2的高三位,则高三位为100,对应3-8译码器的话,P2^7=1;P2^6=0;P2^5=0;
所以输出Y4=0;Y4再经过与非运算,看下图示:
则输出Y4C=1;即LED对应的锁存器的片选信号被选中,锁存器打通,接下来就可以对P0口进行操作,操作完之后,
P2=P2&0x1f;P2高三位直接清零,此时Y4C=0,则把锁存器锁上了。
类似的方法,数码管、蜂鸣器等都是如此操作,
选中锁存器代码:
P2=((P2&0x1f)|(这里填对应锁存器的位移号))。
二、              数码管动态扫描和定时器
数码管显示分为段选和位选,
数码管定义和显示函数:
code unsigned char tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned chardspbuf[]={10,10,10,10,10,10,10,10};
unsigned chardspcom=0;
void display()
{
//段选,消隐
P2=((P2&0x1f)|0xe0);
P0=0xff;
P2=P2&0x1f;
//位选
P2=((P2&0x1f)|0xc0);
P0=(1<<dspcom);
P2=P2&0x1f;
//段码输入
P2=((P2&0x1f)|0xe0);
P0=tab[dspbuf[dspcom]];
P2=P2&0x1f;
if(++dspcom==8)
       dspcom=0;
}注意:这里1左移dspcom位,刚开始dspcom=0,则1左移dspcom位依旧为1,接着dspcom每次自增1,1对应二进制00000001,即把1每次向左移,每次都比上一次多移一位,直至8位移完,对应8个数码管。
定时器配置:
这里只需记住定时器的配置,知道怎么使用就可以了。首先有两个定时器,T0和T1,(也有的单片机有T2),定时器有4种工作方式0,1,2,3;其中最常用的是方式1(16位),其次是方式2(8位自动重装,串口通讯中断会用到)。
定时器需要配置:TMOD |=0x01;配置成使用定时器0,工作方式为1;同理使用定时器1工作方式1:TMOD|=0x10;则同时使用两个定时器且工作方式为1,那么可以:TMOD|=0x11;
定时器1配置成工作方式2:TMOD |=0x20;
接着配置(以定时器0举例):
TH0=(65535-2000)/256;//配置初值
TL0=(65535-2000)%6;
ET0=1;
TR0=1;//定时0中断
EA=1;//总中断
定时器1也是同理的,只不过0要改成1.
接着定时中断函数和优先级:
定时器0
void isr_timer_0(void) interrupt1  //默认中断优先级1
{
    TH0= (65536-2000)/256;
    TL0= (65536-2000)%6;  //定时器重载
   display();
}
定时器1:
voidisr_timer_1(void)  interrupt 3 //默认中断优先级3
{
    TH0= (65536-2000)/256;
    TL0= (65536-2000)%6;  //定时器重载
   display();
}
注意:定时器0优先级为1,定时器13,串口中断优先级为4,总共有5个中断源,后面还会介绍外部中断和串口中断。

数码管动态扫描,显示函数放在定时中断函数里面,2ms扫一次是最稳定的!!

三、              矩阵键盘
矩阵键盘需要死记了!这里不再讲独立键盘。
第二种单片机键盘扫描代码(没有消抖):
sfrP4^4=0xC0;
//键盘定义
sbitr1=P3^0;  //4行
sbit r2=P3^1;
sbit r3=P3^2;
sbit r4=P3^3;
//4列
sbit c1=P4^4;
sbit c2=P4^2;
sbit c3=P3^5;
sbit c4=P3^4;
//读取矩阵键盘键值
unsigned charkey_scan()
{
    unsigned char key_value;
    r1=0;
    r2=r3=r4=1;
    c1=c2=c3=c4=1;
    if(!c1) key_value=0;
    else if(!c2) key_value=1;
    else if(!c3) key_value=2;
    else if(!c4) key_value=3;
   r2=0;
    r1=r3=r4=1;
    c1=c2=c3=c4=1;
    if(!c1) key_value=4;
    else if(!c2) key_value=5;
    else if(!c3) key_value=6;
    else if(!c4) key_value=7;
    r3=0;
    r2=r1=r4=1;
    c1=c2=c3=c4=1;
    if(!c1) key_value=8;
    else if(!c2) key_value=9;
    else if(!c3) key_value=10;
    else if(!c4) key_value=11;
    r4=0;
    r2=r3=r1=1;
    c1=c2=c3=c4=1;
    if(!c1) key_value=12;
    else if(!c2) key_value=13;
    else if(!c3) key_value=14;
    else if(!c4) key_value=15;
    return key_value;
}
四、              串口通讯和串口中断
串口中断配置只需记住几个寄存器就行了,
初始化:
  SCON =0x50; //串口配置成模式1
TMOD|=0x20;//定时器1,方式2,8位自动重装
TH1=256-(unsigbedchar)(SYSTEMCLOK/BAUDRATE/384+0.5);//定时初值
        ES=1;        //串口中断打开
        TR1=1;     //启动定时器1
        EA=1;           //总中断打开
这里必须使用定时器1,不能用定时器0.
下面是模块化的函数:
void Uart_Init()
{
SCON = 0x50;
TMOD |=0x20;
TH1=256-(SYSREMCLOCK/BAUDRATE/384+0.5);
ES=1;
TR1=1;
EA=1;
}
void UartSend(unsignedchar*pBuff,int length)
{
unsigned charc;
int i=0;
for(i=0;i
{
c=pBuff;
SBUF=c;
while(TI==0);
TI=0;
}
}
接收数据可以这样写:
定义全局变量:
unsigned charuart_buf[100];//串口缓冲区
unsignedint  uart_Count=0;//串口数据长度
void uart_inte()interrupt 4
{
     unsigned char c;
     if(RI)
     {
            RI=0;
            c=SBUF;
            uart_buf[uart_Count]=c;
            uart_Count++;
     }                          
}
如果可以指定的接收,可以这样写
//串口中断服务函数
void isr_uart(void)interrupt 4{
   if(RI){
       RI = 0;  //清除接收标志位
       rxbuf[rxcnt] = SBUF;
       if(rxbuf[rxcnt] == '\n'){
           rxcnt = 0;
           rx_over = 1;
           ES = 0;
//回车为接收结束标志,检测到回车符后,关闭串口中断
       }     
            else{
                   rxcnt++;
            }
   }
}
当接收完一帧数据时关闭串口中断,设一个标志位,处理完之后再打开。
#include"reg51.h"
#include"intrins.h"
typedef unsigned charBYTE;
typedef unsigned intWORD;
BYTEcode_tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
char arry[10]="I CANPLAY";
unsigned charx;
#define FOSC11059200//12000000L         //系统频率
#define BAUD115200            //串口波特率
#defineNONE_PARITY    0      //无校验
#defineODD_PARITY     1      //奇校验
#defineEVEN_PARITY    2      //偶校验
#defineMARK_PARITY    3      //标记校验
#defineSPACE_PARITY   4      //空白校验
#define PARITYBITNONE_PARITY  //定义校验位
sfrAUXR  =0x8e;              //辅助寄存器
sfrP_SW1   =0xA2;            //外设功能切换寄存器1
#define S1_S00x40             //P_SW1.6
#define S1_S10x80             //P_SW1.7
sbit P22 =P2^2;
bit busy;
void SendData(BYTEdat);
void SendString(char*s);
void main()
{
    ACC= P_SW1;
    ACC&= ~(S1_S0 |S1_S1);   //S1_S0=0 S1_S1=0
   P_SW1 =ACC;               //(P3.0/RxD, P3.1/TxD)
   
//  ACC= P_SW1;
//  ACC&= ~(S1_S0 |S1_S1);   //S1_S0=1 S1_S1=0
//  ACC|=S1_S0;              //(P3.6/RxD_2, P3.7/TxD_2)
// P_SW1 = ACC;
//
//  ACC= P_SW1;
//  ACC&= ~(S1_S0 |S1_S1);   //S1_S0=0 S1_S1=1
//  ACC|=S1_S1;              //(P1.6/RxD_3, P1.7/TxD_3)
// P_SW1 = ACC;
//#if (PARITYBIT ==NONE_PARITY)
    SCON=0x50;               //8位可变波特率
//#elif (PARITYBIT ==ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT ==MARK_PARITY)
//  SCON =0xda;               //9位可变波特率,校验位初始为1
//#elif (PARITYBIT ==SPACE_PARITY)
//  SCON =0xd2;               //9位可变波特率,校验位初始为0
//#endif
    AUXR=0x40;               //定时器1为1T模式
    TMOD=0x20;               //定时器1为模式2(8位自动重载)
    TL1= (256 - (FOSC/32/BAUD));  //设置波特率重装值
    TH1= (256 - (FOSC/32/BAUD));
    TR1=1;                   //定时器1开始工作
    ES =1;                    //使能串口中断
    EA =1;
   while(1)
     {
//  SendString(arry);
     SendString("I CAN PLAY~~\r\n");//上位机显示接收文本模式
//  SendData(x);
     }
}
void Uart() interrupt 4using 1
{
    if(RI)//单片机接收数据,发送数字0~9,可在数码管上显示,发送hex模式
   {
       RI =0;                //清除RI位
//       P0= SBUF;
            x=SBUF;//将缓存器的数据赋值给x
            P0=0xff;               //消隐
            P2|=0xe0;
            P2&=0x1f;
            
            P0=code_tab[x];               //段选
            P2|=0xe0;
            P2&=0x1f;
            
            P0=0x01;                          //位选第一位
            P2|=0xc0;
            P2&=0x3f;
   
   }
    if(TI)
   {
       TI =0;                //清除TI位
       busy =0;              //清忙标志
   }
}
void SendData(BYTEdat)
{
   while(busy);              //等待前面的数据发送完成
    ACC=dat;                 //获取校验位P (PSW.0)
    if(P)                     //根据P来设置校验位
   {
#if (PARITYBIT ==ODD_PARITY)
       TB8 =0;               //设置校验位为0
#elif (PARITYBIT ==EVEN_PARITY)
       TB8 =1;               //设置校验位为1
#endif
   }
   else
   {
#if (PARITYBIT ==ODD_PARITY)
       TB8 =1;               //设置校验位为1
#elif (PARITYBIT ==EVEN_PARITY)
       TB8 =0;               //设置校验位为0
#endif
   }
    busy= 1;
    SBUF=ACC;                //写数据到UART数据寄存器
}
void SendString(char*s)
{
   while(*s)                 //检测字符串结束标志
   {
       SendData(*s++);        //发送当前字符
   }
}
记不住可以看手册!!
#include"reg51.h"
#include"intrins.h"
typedef unsigned charBYTE;
typedef unsignedint  WORD;
#define FOSC11059200L
#define BAUD115200
sfrAUXR=0x8e;   //辅助寄存器
sbit P22=P2^2;
bit busy;
void SendData(BYTEdat);
void SendString(char*s);
void main()
{
     SCON=0x50;
     AUXR=0x40; //设置定时器T1为1T,即一个机器周期模式
     TMOD=0x20;
     TL1=(256-(FOSC/32/BAUD));
     TH1=(256-(FOSC/32/BAUD));
     TR1=1;
     ES=1;
     EA=1;
     SendString("Hello");
     while(1);
}
void Uart() interrupt 4using 1
{
     if(RI)
     {
            RI=0;
            P0=SBUF;
     }
     if(TI)
     {
            TI=0;
            busy=0;
     }
}
void SendData(BYTEdat)
{
     while(busy);
     busy=1;
     SBUF=dat;
}
void SendString(char*s)
{
     while(*s)
     {
            SendData(*s++);
     }
}
五、              外部中断的使用
#include
sbit L1=P0^0;
int main(){
IT0=1;//IT0=1,下降沿触发外部中断0,IT0=0边沿触发
EX0=1;//使用外部中断0
EA=1;
while(1){
       }
}
void Ex_int0() interrupt 0 //外部中断优先级最高
{
P2=((P2&0x1f)|0x80);
L1=~L1;
P2=(P2&0x1f);
}     


其中,外部中断的引脚控制是P3^2P3^3,即对应独立按键的S5S4

六、              实时时钟DS1302的使用
蓝桥杯提供函数,解释为:
里面的命令和写入的数据可以看芯片手册:
左侧的READ、WRITE分别是读写的命令,BIT7-BIT0是要写入的数据,根据需要进行配置。DS1302只需记住这两个函数即可:Write_Ds1302( , )与Read_Ds1302(x),配置看手册。
重点:芯片表说明:第一行:秒->因为秒的范围是0-59,所以6,5,4位表示秒的十位,3,2,1,0表示个位,十位最大是5,所以三位即可。
第二行:跟上面一样;
第三行:7位:1为12小时制,0为24小时制;5位:12小时制时为0表示上午,1表示下午,24小时制时,和4位一起表示小时的十位;
其余的时间一样的表示。
倒数第二行:只看7位:为1时禁止写数据,所以开始写数据时必须置0;
读数时:
!!需要加“写操作这一行代码”。
读的话直接按照命令读即可。
DS1302进阶(BCD码转换):解决之前60秒不能进位的问题。
1)写入初始值时,要把10十进制数转换为BCD码,
例:写入时间->17:58:50
Ds1302_Single_Byte_Write(0x8e,0x00);//写操作
Ds1302_Single_Byte_Write(0x85, ((17/10)<<4 |(17)));//写时
   Ds1302_Single_Byte_Write(0x83, ((58/10)<<4 |(58)));//写分
Ds1302_Single_Byte_Write(0x81, ((50/10)<<4 |(50)));//写秒
Ds1302_Single_Byte_Write(0x8e,0x80);//写保护
即转换的公式是:((Value/10)<<4 | (Value)),可以写一个settime()函数。
2 )读数:读回来的数要进行转换成十进制数
((ReadValue&0x70)>>4)*10 +(ReadValue&0x0F);
八进制转十进制->
ReadValue=Ds1302_Single_Byte_Read(0x85);
         hour=((ReadValue&0x70)>>4)*10 +(ReadValue&0x0F);
   !!(这句一定不要省)     Ds1302_Single_Byte_Write(0x00, 0x00);//写操作
         ReadValue=Ds1302_Single_Byte_Read(0x83);
         minute=((ReadValue&0x70)>>4)*10 +(ReadValue&0x0F);
         Ds1302_Single_Byte_Write(0x00, 0x00);//写操作
         ReadValue=Ds1302_Single_Byte_Read(0x81);
         sec=((ReadValue&0x70)>>4)*10 +(ReadValue&0x0F);
         Ds1302_Single_Byte_Write(0x00, 0x00);//写操作
显示:
        dspbuf[0]=hour/10;
         dspbuf[1]=hour;
         dspbuf[2]=minute/10;
     dspbuf[3]=minute;
         dspbuf[4]=sec/10;
         dspbuf[5]=sec;
七、              PCF8591与IIC总线的使用
(1)   IIC总线的使用:
比赛提供了IIC的两个库文件,IIC.h;IIC.c,其中需要注意的函数是:
其中,该函数是初始化的,当使用AD转换的时候需要在main函数开始时调用,该函数内部只需看这句代码即可:i2c_sendbyte(0x03);//ADC通道3,板上有4个模拟输入口,分别为0,1,2,3;设置哪一个模拟输入口就是根据这句代码,0x03表示通道3,这是根据芯片手册配置的,如图:
8位前6位不用管,都为0,最后两位就是配置选择哪一个通道的。
第二个函数:
读取AD转换后的数值,这个函数直接调用就可以了,函数内部如何实现不用管,但是需要注意的是:该函数扫描调用最好是100ms。
第三个函数,上面的都是AD转换,即模拟信号转数字信号,下面这个函数是DA转换,数字信号转换成模拟信号,就是单片机输出数字信号,用万能表去量单片机引出的引脚,量一下电压大小,这个估计比赛不会考,不过预防万一:
该函数和上面两个函数分离开来的,一、二函数是要在一起使用,初始化后之后才能调用,第三个加入头文件,直接调用即可,比较简单!!
上面说法有误,A/D转换的初始化函数和读取转换后的数值都需要自己写。
这里了解一下PCF8591只需根据时序格式发送地址字节和控制字节:,这是地址字节,其中A2,A1,A0硬件已经接地,故都为0,最低位表示的是你要从IIC总线上读数还是写数据,1表示读,0表示写,即读数据发的地址是:0x91;写数据发的地址是0x90;
控制字节:
由芯片资料知,控制字节有8位,有两位固定是0,除了第0、1位需要自己设置,其他的我们都设为0,那些位都是一些具体的功能,我们暂时用不着,不用管先,第0、1位是模拟通道选择,PCF8591上提供了4路模拟通道,根据需求进行选择,如选择通道3即发送控制字节:0x03;
地址字节和控制字节都明白了,接下来根据时序要求进行配置,A/D转换需要一个初始化函数:Init_ADpcf8591();和一个获得AD转换后的数值的函数:adc_pcf8591(); 其中初始化函数的作用是发送AD转换的控制字节;adc_pcf8591()发送读取得地址并读回数据,先写指令才能读;格式如下:
这个是初始化的协议:分别是startIIC、(地址写)发送0x90、等待应答、发送控制字节(AD这里是选择通道的指令,如选择通道3,0x03)0x03、等待应答、(达到目的,没有后续的操作,直接停止总线)StopIIC.
初始化的函数就是如此写;
adc_pcf8591的协议:
依次是:startIIc、发送读地址0x91、等待应答、读回AD转换后的数值、读回后发送应答给PCF8591,表示收到,并且不需要再返回应答,要传参数1,如图红圈示,即函数Ack(1);、最后stopIIC总线。
D/A转换(其实挺麻烦,先前太自信了,哈):
所谓D/A转换其实就是把数字信号转换成模拟信号输出,用单片机发数字通过D/A转换成电压输出,检测的方法可以用电压表测量。
配置的方法跟A/D类似,先发地址字节,再发控制字节,然后把数字发出去(AD这里是接收模拟信号,是相反的机制)。
控制字节:
如图示,控制字节的第6位是1的话是模拟输出模式,其余位全为0,发送格式跟AD一样:
代码如一开始图示。

(2)   EEPROM的使用,AT24C02,可以掉电依旧保存上一次操作的数据,下次上电后接着运行。
需要注意两个函数,一个是写进EEPROM里面保存,再次上电再从里面读回来:
其中写函数需要指定AT24C02的地址以及需要写入的数据,读函数要想取回写进的数据,需要从相同的地址里面读:
其中AT24C02的存储地址是0x00,可以是其他地址,如0x02,但是读和写的地址必须一致。
写与读的协议与AD或DA相同,
由芯片资料及原理图知EEPROM(AT24C02)的写地址为0xa0;读地址为0xa1;注意:读数的时候读出一个数之后发送一个应答信号,若ACK(0)表示还想继续读下一个字节,若ACK(1);则不想再读数,让EEPROM停止发送。
八、              DS18B20时钟芯片的使用
比赛有提供代码,只需记住这个函数:
读取温度值,整数(其中,提示EA总中断要打开、关闭,也可以不用)。
浮点数的表示。
注意,只有提供函数,没有提供读取温度的函数,即上面的那个,只有下面:这几个函数。
编写读取温度的函数需要记住DS13B20的三条指令,0xCC,跳过ROM检测;然后启动温度转换:0x44;转换需要时间,这里精确延时Delay_OneWire(200);然后再次初始化,再次执行跳过,然后读取温度指令:0xBE.;注意读出的温度是低字节先,然后才是高字节,分别用两个变量保存还要通过公式转换成我们需要的整数或浮点数。完整代码如上图示。
九、              超声波传感器的使用
#include"reg52.h"  //定义51单片机特殊功能寄存器
#include "intrins.h"
#include "absacc.h"
//12M用这个
//11.0592用这个
#define somenop{_nop_();_nop_();_nop_();_nop_();_nop_();
                _nop_();_nop_();}
sbit TX =P1^0;  //发射引脚
sbit RX =P1^1;  //接收引脚
code unsigned char tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
                            0xff};
unsigned char dspbuf[8] ={10,10,10,10,10,10,10,10};  //显示缓冲区
unsigned char dspcom =0;
unsigned int intr =0;
bit s_flag;
unsigned int t = 0;
voidsend_wave(void);
void display(void);
void main(void)
{
   unsigned int distance;
    TMOD|= 0x11;  //配置定时器工作模式
    TH0= (65536-2000)/256;
    TL0= (65536-2000)%6;
    TH1= 0;
    TL1= 0;
    EA =1;
    ET0= 1;  //打开定时器0中断
    TR0= 1;  //启动定时器  
   while(1){
      
       if(s_flag)
       {
           s_flag = 0;
           
                     t = TH1;
                     t <<= 8;
                     t |= TL1;
                     distance = (unsigned int)(t*0.017); //计算距离                          
              }
              TH1 = 0;
              TL1 = 0;
       }
      
                    
       dspbuf[5] = distance/100;
       dspbuf[6] = distance0/10;
       dspbuf[7] =distance;      
   }
}
//定时器0中断服务函数
voidisr_timer_0(void)  interrupt 1 //默认中断优先级 1
{
    TH0= (65536-2000)/256;
    TL0= (65536-2000)%6;  //定时器重载
   
display(); //2ms执行一次
if(++intr == 200){
       s_flag = 1;
       intr = 0;
   }
}
//显示函数
void display(void){
      XBYTE[0xE000] = 0xff;  //去除鬼影
      XBYTE[0xC000] = (1<<dspcom);
      XBYTE[0xE000] = tab[dspbuf[dspcom]];
if(++dspcom == 8){
             dspcom = 0;
}     
}
//TX引脚发送40KHz方波信号驱动超声波发送探头
void send_wave(void)
{
unsigned char i =8;  //发送8个脉冲
do
{
       TX = 1;
       somenop;
       TX = 0;
       somenop;
}
while(i--);
}
必要时还可以加个看门狗:   WDT_CONTR=0x34;
十、              步进电机与直流电机的使用
参考代码如下:
#include
sbit A1=P1^4;//定义步进电机连接端口
sbit B1=P1^3;
sbit C1=P1^2;
sbit D1=P1^1;
void qudong1();
#define Dy_A1{A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电
#define Dy_B1{A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电
#define Dy_C1{A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电
#define Dy_D1{A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电    //采用1相励磁
#define Dy_OFF{A1=0;B1=0;C1=0;D1=0;}//全部断电
unsigned charSpeed,Speed1;
void DelayUs2x(unsigned chart)
{  
while(--t);
}
void DelayMs(unsigned chart)
{
   
while(t--)
{
    //大致延时1mS
    DelayUs2x(245);
   DelayUs2x(245);
}
}
main()
{
Dy_OFF;
for(;;)
{
   qudong1();
  }
}
void qudong1()
{
unsigned inti=470;//旋转一周时间
Speed=5;
while(i--)  //正向
{        
    Dy_A1               
//遇到Coil_A1  用{A1=1;B1=0;C1=0;D1=0;}代替
    DelayMs(Speed);        
//改变这个参数可以调整电机转速,
                            //数字越小,转速越大,力矩越小
    Dy_B1                              //顺序从A1--D1相通电如果为正转,那么顺序从D1--A1相通电则为反转
    DelayMs(Speed);
    Dy_C1
    DelayMs(Speed);
    Dy_D1
    DelayMs(Speed);
  }
Dy_OFF
i=512;
while(i--)//反向
  {
    Dy_D1               //遇到Coil_A1  用{A1=1;B1=0;C1=0;D1=0;}代替
    DelayMs(Speed);        //改变这个参数可以调整电机转速,
                          //数字越小,转速越大,力矩越小
    Dy_C1
    DelayMs(Speed);
    Dy_B1
    DelayMs(Speed);
    Dy_A1
    DelayMs(Speed);
}      
}
直流电机:
#include
#define uint unsigned int
voiddrive();
voiddelay(uint);
sbitdj1=P1^0; //电机,1引脚
uintset; //set为电机转角标志位
unsigned charangle,angle1;  //angle为电机PWM变化打角
voidTime0_Init()      //中断初始化
{
TMOD=0X01;
IE=0X82;
TH0=(65536-58)/256;           
TL0=(65536-58)%6;
TR0=1;
}
voidmain()        //主函数
{
set=0;
angle=62;  // 改变angle的值可以改变电机的占空比
Time0_Init();
  for(;;)
   {
   }   
}
voidT0_time()interrupt 1
{
TH0=(65536-58)/256;           
TL0=(65536-58)%6;
  if(set
   dj1=1;
else
  dj1=0;
set++;
if(set>165)set=0;   //电机占空比
}
十一、    扩展:宏定义编程方法(推荐)
常用的可以宏定义,省时,下面以数码管为例:
#define rst573P2&=0x1f
#define Y6CP2=  ((P2&0x1f)|0xc0)
#define Y7CP2=  ((P2&0x1f)|0xe0)
code unsigned char tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char dspbuf[8] ={10,10,10,10,10,10,10,10};  //显示缓冲区
unsigned chardspcom;
unsigned char flag;
void display()
{
Y7C;
P0=0xff;
rst573;
Y6C;
P0=1<<dspcom;
rst573;
Y7C;
P0=tab[dspbuf[dspcom]];
rst573;
if(++dspcom==8)
       dspcom=0;
}

评分

参与人数 3黑币 +20 收起 理由
SE555D + 5 很给力!
芦苇劫 + 10 绝世好帖!
sky日耀 + 5 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏17 分享淘帖 顶3 踩
回复

使用道具 举报

沙发
ID:86461 发表于 2015-12-5 10:56 | 只看该作者
好东西,感谢楼主分享
回复

使用道具 举报

板凳
ID:91159 发表于 2016-2-5 09:52 | 只看该作者
谢谢你,我想问一下,我可不可以理解为,蓝桥杯单片机组对程序的要求是,除了时序程序,都要求自己写
回复

使用道具 举报

地板
ID:105191 发表于 2016-2-8 19:43 | 只看该作者
感谢楼主分享的好东西!
回复

使用道具 举报

5#
ID:107035 发表于 2016-3-2 19:57 | 只看该作者
蟹蟹楼主O(∩_∩)O
回复

使用道具 举报

6#
ID:109424 发表于 2016-3-17 22:25 来自手机 | 只看该作者
谢楼主分享
回复

使用道具 举报

7#
ID:119181 发表于 2016-5-7 23:42 来自手机 | 只看该作者
楼主,在吗,我有点问题想请教你,527334445我qq,我比较急
回复

使用道具 举报

8#
ID:119181 发表于 2016-5-7 23:43 来自手机 | 只看该作者
看到回复一下吧
回复

使用道具 举报

9#
ID:153765 发表于 2016-12-16 17:24 | 只看该作者
15454555
回复

使用道具 举报

10#
ID:156157 发表于 2016-12-20 10:21 | 只看该作者
感谢楼主
回复

使用道具 举报

11#
ID:161530 发表于 2017-1-14 13:10 | 只看该作者
楼主,想问个问题,keil uVision4  怎么建CT107D的工程?找不到 芯片类型
回复

使用道具 举报

12#
ID:253249 发表于 2018-1-9 12:05 来自手机 | 只看该作者
可以认识楼主一下吗?
回复

使用道具 举报

13#
ID:279179 发表于 2018-1-24 17:26 | 只看该作者
请问为什么看不见图呢?
回复

使用道具 举报

14#
ID:279179 发表于 2018-1-24 17:31 | 只看该作者
楼主你好,上线后可以回复一下吗?谢谢你,有些问题不太清楚想向你学习一下
回复

使用道具 举报

15#
ID:272080 发表于 2018-1-25 10:07 | 只看该作者
这个可能只有参加比赛的才能看得懂啊哈哈
回复

使用道具 举报

16#
ID:281313 发表于 2018-2-1 00:08 | 只看该作者
楼主前面说错了,应该是或非门
回复

使用道具 举报

17#
ID:361383 发表于 2019-3-1 16:36 | 只看该作者
好东西!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表