零、引脚

  • 0 宏定义数码管段码口 点阵列控制端口
  • 1 右下角矩阵按键控制口
  • 1.0 直流电机控制管脚
  • 1.0 1.1 1.2 1.3 控制步进电机管脚
  • 2.0 右边的LED
  • 2.1 SCL时钟线 2.0 SDA数据线
  • 2.2 2.3 2.4 左上角的数码管
  • 2.5 蜂鸣器
  • 3.1 3.0 3.2 3.3 左下角的四个独立按键控制脚
  • 3.4 串行数据输入
  • 3.5 存储寄存器时钟输入
  • 3.6 移位寄存器时钟输入

一、跑马灯

/*单个灯闪烁LED1=0; //点亮delay_10us(50000); //大约延时 4500msLED1=1; //熄灭delay_10us(50000);
*/
/*跑马灯u8 i;for (i = 0; i < 8; i ++){LED_PORT = ~(0x01 << i);delay_10us(50000);}
*/
/*循环跑马灯for (i = 1; i < 8; i ++){LED_PORT = _crol_(LED_PORT, 1);delay_10us();}for (i = 1; i < 8; i ++){LED_PORT = _cror_(LED_PORT, 1);delay_10us();}
*/

二、蜂鸣

原理:该蜂鸣器是无源的,加上扰动才能发音。

一定要在外面加上while(1),但原因不知道。

     while (i --){BEEP = !BEEP;delay_10us();} i = 0;

三、静态显示

将a~小数点的01写出来后反过来 最顶的是a 他右边的是b 转个圈

只能显示最左边的一个位置

1000 0111 计算时为 1110 1000e1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iolf02To-1655964413878)(https://i.bmp.ovh/imgs/2022/06/20/3b17585168ab885f.png)]

#include "reg52.h"
//#include "intrins.h"//#define LED_PORT P2 //使用宏定义   LED灯
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口 左上角的第0个//sbit LED1=P2^7;
//sbit BEEP=P2^5; //将 P2.5 管脚定义为 BEE 蜂鸣器typedef unsigned int u16; //对系统默认数据类型进行重命名
typedef unsigned char u8;void delay_10us()
{u16 ten_us = 50000;while(ten_us--);
}void main(){//共阴极数码管显示 0~F 的段码数据//将a~小数点的01写出来后反过来u8 gsmg_code[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};u16 i;for (i = 0; i < 16; i ++){SMG_A_DP_PORT = gsmg_code[i];//将数组第 1 个数据赋值给数码管段选口delay_10us();}while (1){}
}

四、动态数码管

似乎只能把三个引脚设为2.2、2.3、2.4

理解成三个引脚合成一个位置。

ABC是234,写的时候以CBA来看。如此时C=0; B=0; A = 1,那么他表示的是从右到左第1个位置。

实现从右往左跑马灯“HELLO WORLD”

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:动态数码管实验
接线说明:
实验现象:下载程序后“数码管模块”显示01234567
注意事项:
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;#define SMG_A_DP_PORT  P0  //使用宏定义数码管段码口//定义数码管位选信号控制脚
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;//HELLO WORLD
u8 gsmg_code[17]={0x76, 0x79, 0x38, 0x38, 0x3f, 0x00, 0x3c, 0x1e, 0x3f, 0x50, 0x38, 0x5e, 0x00, 0x00}; //14/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while(ten_us--);
}/*******************************************************************************
* 函 数 名       : smg_display
* 函数功能       : 动态数码管显示
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void smg_display(void)
{u8 i = 0;u8 t, k, j;u8 show_code[8];//HELLO WOrLd 从右到左while (1){i = (i) % 14;      //将要加进来的输出数组下标for (k = 0; k < 7; k ++) show_code[k] = show_code[k + 1];show_code[7] = gsmg_code[i ++];//每次输出一个长度为8的数组t = 100;     while (t --){for (j = 0; j < 8; j ++){switch(j)//位选{case 0: LSC=1;LSB=1;LSA=1;break;case 1: LSC=1;LSB=1;LSA=0;break;case 2: LSC=1;LSB=0;LSA=1;break;case 3: LSC=1;LSB=0;LSA=0;break;case 4: LSC=0;LSB=1;LSA=1;break;case 5: LSC=0;LSB=1;LSA=0;break;case 6: LSC=0;LSB=0;LSA=1;break;case 7: LSC=0;LSB=0;LSA=0;break;}SMG_A_DP_PORT=show_code[j];//传送段选数据delay_10us(100);//延时一段时间,等待显示稳定SMG_A_DP_PORT=0x00;//消音}}delay_10us(100);}
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   while(1){smg_display();}
}

五、独立按键

按键被按时被按的变为0,电流变化是输入

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:独立按键实验
接线说明:
实验现象:下载程序后,按下“独立按键”模块中K1键,控制D1指示灯亮灭
注意事项:
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义独立按键控制脚
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;//定义LED1控制脚
sbit LED1=P2^0;//使用宏定义独立按键按下的键值
#define KEY1_PRESS  1
#define KEY2_PRESS  2
#define KEY3_PRESS  3
#define KEY4_PRESS  4
#define KEY_UNPRESS 0   /*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while(ten_us--);
}/*******************************************************************************
* 函 数 名       : key_scan
* 函数功能       : 检测独立按键是否按下,按下则返回对应键值
* 输    入       : mode=0:单次扫描按键mode=1:连续扫描按键
* 输    出         : KEY1_PRESS:K1按下KEY2_PRESS:K2按下KEY3_PRESS:K3按下KEY4_PRESS:K4按下KEY_UNPRESS:未有按键按下
*******************************************************************************/
u8 key_scan(u8 mode)
{static u8 key=1;if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按键按下{delay_10us(1000);//消抖key=0;if(KEY1==0)return KEY1_PRESS;else if(KEY2==0)return KEY2_PRESS;else if(KEY3==0)return KEY3_PRESS;else if(KEY4==0)return KEY4_PRESS;    }else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)    //无按键按下{key=1;         }return KEY_UNPRESS;
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   u8 key=0;while(1){key=key_scan(0);if(key==KEY1_PRESS)//检测按键K1是否按下LED1=!LED1;//LED1状态翻转 }
}

六、矩阵按键

8个I/O口,4行4列

先行后列,从左往右分别代表1234

每加一行加4,结果加列。0表示被按下。

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:矩阵按键实验
接线说明:
实验现象:下载程序后,按下“矩阵按键”模块中S1-S16键,对应数码管最左边显示0-F
注意事项:
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;#define KEY_MATRIX_PORT    P1  //使用宏定义矩阵按键控制口      #define SMG_A_DP_PORT   P0  //使用宏定义数码管段码口//共阴极数码管显示0~F的段码数据
u8 gsmg_code[17] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while (ten_us--);
}/*******************************************************************************
* 函 数 名       : key_matrix_flip_scan
* 函数功能       : 使用线翻转扫描方法,检测矩阵按键是否按下,按下则返回对应键值
* 输    入       : 无
* 输    出         : key_value:1-16,对应S1-S16键,0:按键未按下
*******************************************************************************/
u8 key_matrix_flip_scan(void)
{static u8 key_value = 0;KEY_MATRIX_PORT = 0x0f;//给所有行赋值0,列全为1if (KEY_MATRIX_PORT != 0x0f)//判断按键是否按下{delay_10us(1000);//消抖if (KEY_MATRIX_PORT != 0x0f){//测试列KEY_MATRIX_PORT = 0x0f;switch (KEY_MATRIX_PORT)//保存行为0,按键按下后的列值  {case 0x07: key_value = 1; break;case 0x0b: key_value = 2; break;case 0x0d: key_value = 3; break;case 0x0e: key_value = 4; break;}//测试行KEY_MATRIX_PORT = 0xf0;switch (KEY_MATRIX_PORT)//保存列为0,按键按下后的键值  {case 0x70: key_value = key_value; break;case 0xb0: key_value = key_value + 4; break;case 0xd0: key_value = key_value + 8; break;case 0xe0: key_value = key_value + 12; break;}while (KEY_MATRIX_PORT != 0xf0);//等待按键松开 }}elsekey_value = 0;return key_value;
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{u8 key = 0;while (1){key = key_matrix_flip_scan();if (key != 0)SMG_A_DP_PORT = gsmg_code[key - 1];//得到的按键值减1换算成数组下标对应0-F段码     }
}

七、IO 扩展

右上角的点阵

u8 ghc595_buf[8]={0x01,0x02,0x03,0x0f,0x10,0x20,0x40,0x80};

最下面是0000 0001(0x01),最上面是1000 0000(0x80)

移位寄存器 -> 存储寄存器 传东西

如果两个时钟连在一起,则移位寄存器总是比存储器早一个脉冲

for 循环里面最好不要有等于。可能是精度问题。

将LED点阵列全部设置为0,即LED阴极为低电平,当有1时亮灯。

将移位寄存器和存储器置0置1表示传输数据。

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:IO扩展(串转并)实验-74HC595
接线说明:
实验现象:下载程序后,8*8LED点阵以一行循环滚动显示
注意事项:LED点阵旁的J24黄色跳线帽短接到GND一端
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义74HC595控制管脚
sbit SRCLK=P3^6;   //移位寄存器时钟输入
sbit RRCLK=P3^5;       //存储寄存器时钟输入
sbit SER=P3^4;         //串行数据输入#define LEDDZ_COL_PORT  P0  //点阵列控制端口u8 ghc595_buf[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while(ten_us--);
}/*******************************************************************************
* 函 数 名       : delay_ms
* 函数功能       : ms延时函数,ms=1时,大约延时1ms
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_ms(u16 ms)
{u16 i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);
}/*******************************************************************************
* 函 数 名         : hc595_write_data(u8 dat)
* 函数功能         : 向74HC595写入一个字节的数据
* 输    入         : dat:数据
* 输    出         : 无
*******************************************************************************/
void hc595_write_data(u8 dat)
{u16 i;//不能在大循环里写上大于等于 推测精度原因for(i = 8; i > 0; i--)//循环8次即可将一个字节写入寄存器中{SER = (dat >> (i - 1)) & 1;//优先传输一个字节中的高位//   dat <<= 1;//将低位移动到高位SRCLK=0;delay_10us(1);SRCLK=1;delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中    }RRCLK=0;delay_10us(1);RRCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   u8 i=0;LEDDZ_COL_PORT=0x00;//将LED点阵列全部设置为0,即LED阴极为低电平while(1){     for(i=0;i<8;i++){ hc595_write_data(0x00);//消除前面寄存器缓存数据hc595_write_data(ghc595_buf[i]);//写入新的数据delay_ms(500);//延时500ms }                                   }
}

八、LED 点阵实验

8.1 点灯

LEDDZ_COL_PORT=0x00; 设置的是列数。当列数为0时可被点亮、当列数为1时不能被点亮。

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:LED点阵实验(点亮一个点)
接线说明:
实验现象:下载程序后,8*8LED点阵点亮左上角第一个点
注意事项:LED点阵旁的J24黄色跳线帽短接到GND一端
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义74HC595控制管脚
sbit SRCLK = P3 ^ 6;   //移位寄存器时钟输入
sbit rCLK = P3 ^ 5;        //存储寄存器时钟输入
sbit SER = P3 ^ 4;         //串行数据输入#define LEDDZ_COL_PORT  P0  //点阵列控制端口/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while (ten_us--);
}/*******************************************************************************
* 函 数 名         : hc595_write_data(u8 dat)
* 函数功能         : 向74HC595写入一个字节的数据
* 输    入         : dat:数据
* 输    出         : 无
*******************************************************************************/
void hc595_write_data(u8 dat)
{u8 i = 0;for (i = 0; i < 8; i++)//循环8次即可将一个字节写入寄存器中{SER = dat >> 7;//优先传输一个字节中的高位dat <<= 1;//将低位移动到高位SRCLK = 0;delay_10us(1);SRCLK = 1;delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中    }rCLK = 0;delay_10us(1);rCLK = 1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{u8 i = 0;LEDDZ_COL_PORT = 0x7f;//将LED点阵左边第一列设置为0,即LED阴极为低电平,其余列为1,即高电平while (1){hc595_write_data(0x87); //行                         }
}

8.2 显示数字、图形

每次亮一列,每列的哪几行看着亮。

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:LED点阵实验(显示数字)
接线说明:
实验现象:下载程序后,8*8LED点阵显示数字0
注意事项:LED点阵旁的J24黄色跳线帽短接到GND一端
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义74HC595控制管脚
sbit SRCLK=P3^6;   //移位寄存器时钟输入
sbit rCLK=P3^5;        //存储寄存器时钟输入
sbit SER=P3^4;         //串行数据输入#define LEDDZ_COL_PORT  P0  //点阵列控制端口u8 gled_row[8]={0x20,0x7F,0x80,0x49,0x7F,0x49,0x4F,0x01};//LED点阵显示数字0的行数据
u8 gled_col[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED点阵显示数字0的列数据/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while(ten_us--);
}/*******************************************************************************
* 函 数 名         : hc595_write_data(u8 dat)
* 函数功能         : 向74HC595写入一个字节的数据
* 输    入         : dat:数据
* 输    出         : 无
*******************************************************************************/
void hc595_write_data(u8 dat)
{u8 i=0;for(i=0;i<8;i++)//循环8次即可将一个字节写入寄存器中{SER=dat>>7;//优先传输一个字节中的高位dat<<=1;//将低位移动到高位SRCLK=0;delay_10us(1);SRCLK=1;delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中   }rCLK=0;delay_10us(1);rCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   u8 i=0;while(1){           for(i=0;i<8;i++)//循环8次扫描8行、列{LEDDZ_COL_PORT=gled_col[i];//传送列选数据hc595_write_data(gled_row[i]);//传送行选数据delay_10us(100);//延时一段时间,等待显示稳定hc595_write_data(0x00);//消影  }                               }
}

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:LED点阵实验(显示数字)
接线说明:
实验现象:下载程序后,8*8LED点阵显示数字0
注意事项:LED点阵旁的J24黄色跳线帽短接到GND一端
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义74HC595控制管脚
sbit SRCLK=P3^6;   //移位寄存器时钟输入
sbit rCLK=P3^5;        //存储寄存器时钟输入
sbit SER=P3^4;         //串行数据输入#define LEDDZ_COL_PORT  P0  //点阵列控制端口u8 gled_row[7][8]={{0x38,0x7C,0x7E,0x3F,0x1F,0x7E,0x7C,0x38},{0x00,0x18,0x3C,0x1E,0x1E,0x3C,0x18,0x00},{0x38,0x7C,0x7E,0x3F,0x1F,0x7E,0x7C,0x38},{0x00,0x18,0x3C,0x1E,0x1E,0x3C,0x18,0x00},{0x10,0x10,0x10,0x10,0x10,0x54,0x38,0x10},{0x60,0xF0,0x7C,0x7E,0xFF,0x6F,0x1E,0x0C},{0x60,0xF0,0x7C,0x7E,0xFF,0x6F,0x1E,0x0C},
};//LED点阵显示数字0的行数据
u8 gled_col[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED点阵显示数字0的列数据/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while(ten_us--);
}/*******************************************************************************
* 函 数 名         : hc595_write_data(u8 dat)
* 函数功能         : 向74HC595写入一个字节的数据
* 输    入         : dat:数据
* 输    出         : 无
*******************************************************************************/
void hc595_write_data(u8 dat)
{u8 i=0;for(i=0;i<8;i++)//循环8次即可将一个字节写入寄存器中{SER=dat>>7;//优先传输一个字节中的高位dat<<=1;//将低位移动到高位SRCLK=0;delay_10us(1);SRCLK=1;delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中   }rCLK=0;delay_10us(1);rCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   u8 i=0, j=0, k=0;while(1){           for (j = 0; j < 7; j ++){k = 50;while (k --){for(i=0;i<8;i++)//循环8次扫描8行、列{LEDDZ_COL_PORT=gled_col[i];//传送列选数据hc595_write_data(gled_row[j][i]);//传送行选数据delay_10us(100);//延时一段时间,等待显示稳定hc595_write_data(0x00);//消影   }}delay_10us(1000);         }}
}

九、直流电机

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:直流电机实验
接线说明:
实验现象:下载程序后,直流电机旋转5S后停止
注意事项:将直流电机两根线分别连接到“步进电机模块”输出端子J47的5V和O1上。
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义直流电机控制管脚
sbit DC_Motor=P1^0;#define DC_MOTOR_RUN_TIME   5000    //定义直流电机运行时间为5000ms/*******************************************************************************
* 函 数 名       : delay_ms
* 函数功能       : ms延时函数,ms=1时,大约延时1ms
* 输    入       : ms:ms延时时间
* 输    出         : 无
*******************************************************************************/
void delay_ms(u16 ms)
{u16 i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   DC_Motor=1;//开启电机delay_ms(DC_MOTOR_RUN_TIME);DC_Motor=0;//关闭电机while(1){           }
}

十、步进电机

控制速度的方法:停止等待。

五条线:1条总电源,4条控制磁。

A->AB->B->BC->C->CD->D->DA 转子每次只走半步 45 度,所以 这也被称为半步驱动,与整步相比半步的旋转方式旋转起来更加的顺滑。

A->B->C->D 也能走,但是当休眠时间很短时就走不动了(该情况下8个分支的还能走)。

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:步进电机实验
接线说明:
实验现象:下载程序后,当按下KEY1键可调节电机旋转方向;当按下KEY2键,电机加速;当按下KEY3键,电机减速
注意事项:将步进电机红色线对接到“步进电机模块”输出端子J47的5V上,其它相序依次接入。
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义ULN2003控制步进电机管脚
sbit IN1_A=P1^0;
sbit IN2_B=P1^1;
sbit IN3_C=P1^2;
sbit IN4_D=P1^3;//定义独立按键控制脚
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;//使用宏定义独立按键按下的键值
#define KEY1_PRESS  1
#define KEY2_PRESS  2
#define KEY3_PRESS  3
#define KEY4_PRESS  4
#define KEY_UNPRESS 0// 定义步进电机速度,值越小,速度越快
// 最小不能小于1
#define STEPMOTOR_MAXSPEED        1
#define STEPMOTOR_MINSPEED        5     /*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while(ten_us--);
}/*******************************************************************************
* 函 数 名       : delay_ms
* 函数功能       : ms延时函数,ms=1时,大约延时1ms
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_ms(u16 ms)
{u16 i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);
}/*******************************************************************************
* 函 数 名       : step_motor_28BYJ48_send_pulse
* 函数功能       : 输出一个数据给ULN2003从而实现向步进电机发送一个脉冲
* 输    入       : step:指定步进序号,可选值0~7dir:方向选择,1:顺时针,0:逆时针
* 输    出         : 无
*******************************************************************************/
void step_motor_28BYJ48_send_pulse(u8 step,u8 dir)
{u8 temp=step;if(dir==0) //如果为逆时针旋转temp=7-step;//调换节拍信号switch(temp)//8个节拍控制:A->AB->B->BC->C->CD->D->DA{case 0: IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=0;break;case 1: IN1_A=1;IN2_B=1;IN3_C=0;IN4_D=0;break;case 2: IN1_A=0;IN2_B=1;IN3_C=0;IN4_D=0;break;case 3: IN1_A=0;IN2_B=1;IN3_C=1;IN4_D=0;break;case 4: IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=0;break;case 5: IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=1;break;case 6: IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=1;break;case 7: IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=1;break;default: IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=0;break;//停止相序    }
}/*******************************************************************************
* 函 数 名       : key_scan
* 函数功能       : 检测独立按键是否按下,按下则返回对应键值
* 输    入       : mode=0:单次扫描按键mode=1:连续扫描按键
* 输    出         : KEY1_PRESS:K1按下KEY2_PRESS:K2按下KEY3_PRESS:K3按下KEY4_PRESS:K4按下KEY_UNPRESS:未有按键按下
*******************************************************************************/
u8 key_scan(u8 mode)
{static u8 key=1;if(mode)key=1;//连续扫描按键if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按键按下{delay_10us(1000);//消抖key=0;if(KEY1==0)return KEY1_PRESS;else if(KEY2==0)return KEY2_PRESS;else if(KEY3==0)return KEY3_PRESS;else if(KEY4==0)return KEY4_PRESS; }else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)    //无按键按下{key=1;         }return KEY_UNPRESS;
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   u8 key=0;u8 dir=0;//默认逆时针方向u8 speed=STEPMOTOR_MAXSPEED;//默认最大速度旋转u8 step=0;while(1){            key=key_scan(0);if(key==KEY1_PRESS)//换向{dir=!dir;    }else if(key==KEY2_PRESS)//加速{if(speed>STEPMOTOR_MAXSPEED)speed-=1;          }else if(key==KEY3_PRESS)//减速{if(speed<STEPMOTOR_MINSPEED)speed+=1;          }step_motor_28BYJ48_send_pulse(step++,dir);if(step==8)step=0;      delay_ms(speed);                        }
}

十一、中断

有点像操作系统里面的0x80

11.1 外部中断(按键)

通常我们 都是使用基本的 2 个外部中断:INT0 和 INT1

INT0 对应的是 P3.2 口的附加功能;INT1 对应的是 P3.3 口的附加功能。

可由 IT0(TCON.0)选择其为低电平有 效还是下降沿有效。当 CPU 检测到 P3.2 引脚上出现有效的中断信号时,中断标 志 IE0(TCON.1)置 1,向 CPU 申请中断。

下降沿:被按下

这里有时红灯一闪一闪,原因:红外接收传感器与 K3 共用 P3.2 口。使用红外线遥控器同样可以开关。

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:外部中断0实验
接线说明:
实验现象:下载程序后,当按下K3键可控制D1指示灯亮灭
注意事项:将红外接收传感器取下,防止对P3.2口干扰
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义LED1管脚
sbit LED1=P2^0;//定义独立按键K3控制脚
sbit KEY3=P3^2;/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while(ten_us--);
}/*******************************************************************************
* 函 数 名       : exti0_init
* 函数功能       : 外部中断0配置函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void exti0_init(void)
{IT0=1;//跳变沿触发方式(下降沿)EX0=1;//打开INT0的中断允许EA=1;//打开总中断
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   exti0_init();//外部中断0配置while(1){         }
}void exti0() interrupt 0 //外部中断0中断函数
{delay_10us(1000);//消斗if(KEY3==0)//再次判断K3键是否按下LED1=!LED1;//LED1状态翻转
}

11.2 定时器中断

工作方式 图片
方式0
方式1
方式2
方式3

51 系列单片机一定有基本的 2 个定时器 (定时器 0 和定时器 1),但不全有 3 个中断,通常我们使 用的是基本的 2 个定时器:定时器 0/1。

常用的是方式1:总体上是TH0和TL0组成一个数字(各8位)做自增,当这个数字自增到溢出时发生一次中断。

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:定时器0实验
接线说明:
实验现象:下载程序后,D1指示灯间隔1s闪烁
注意事项:
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;//定义LED1管脚
sbit LED1=P2^0;/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能       : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出         : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{while(ten_us--);
}/*******************************************************************************
* 函 数 名       : time0_init
* 函数功能       : 定时器0中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void time0_init(void)
{TMOD|=0X01;//选择为定时器0模式,工作方式1TH0=0XFC; //给定时器赋初值,定时1msTL0=0X18;    ET0=1;//打开定时器0中断允许EA=1;//打开总中断TR0=1;//打开定时器
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   time0_init();//定时器0中断配置while(1){            }
}void time0() interrupt 1 //定时器0中断函数
{static u16 i;//定义静态变量iTH0=0XFC;   //给定时器赋初值,定时1msTL0=0X18;i++;if(i==1000){i=0;LED1=!LED1;   }
}

十二、串口通信

实验软件的波特率要和程序里写的波特率一样。

RS232 的通信协议比较简单,通常遵循 96-N-8-1 格式。 “96”表示的是通信波特率为 9600。串口通信中通常使用的是异步串口通 信,即没有时钟线,所以两个设备要通信,必须要保持一致的波特率。

如果使用黄色跳线帽将 P5 端子的 1、2 短接,3、4 短接,那么 CH340 串口与 单片机串口是连接一起的,此时即可实现程序的下载或串口通信。

/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net实验名称:串口通信实验
接线说明:
实验现象:下载程序后,当串口助手发送数据给单片机,单片机原封不动转发给串口助手显示
注意事项:使用黄色跳线帽将CH340旁的P5端子的UTX和P30短接,URX和P31短接,出厂默认已短接好
***************************************************************************************/
#include "reg52.h"typedef unsigned int u16;   //对系统默认数据类型进行重定义
typedef unsigned char u8;/*******************************************************************************
* 函 数 名       : uart_init
* 函数功能       : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : baud:波特率对应的TH、TL装载值
* 输    出         : 无
*******************************************************************************/
void uart_init(u8 baud)
{TMOD|=0X20;   //设置计数器工作方式2SCON=0X50; //设置为工作方式1PCON=0X80;   //波特率加倍TH1=baud;   //计数器初始值设置     TL1=baud;ES=1;     //打开接收中断EA=1;      //打开总中断TR1=1;      //打开计数器
}/*******************************************************************************
* 函 数 名       : main
* 函数功能       : 主函数
* 输    入       : 无
* 输    出         : 无
*******************************************************************************/
void main()
{   uart_init(0XFA);//波特率为9600while(1){         }
}void uart() interrupt 4 //串口通信中断函数
{u16 rec_data;RI = 0;          //清除接收中断标志位rec_data=SBUF;  //存储接收到的数据SBUF=rec_data;   //将接收到的数据放入到发送寄存器while(!TI);        //等待发送数据完成TI=0;            //清除发送完成标志位
}

传入再传出。尝试了下加法,效果步理想。

十三、I2C-EEPROM 实验

只能说这个实验只能勉强理解在干啥。

13.1 项目总览

从这里开始不再是一个光.c文件了。

照着教程配了下文件。下载时记得要换文件路径了。

程序由以下几个功能实现:

功能名称 功能
key 按键检测
smg 数码管显示
iic I2C 读写字节
24c02 AT24C02 读写字节

13.2 通信协议

模拟I2C时序,实现与 AT24C02(EEPROM)之间的双向通信。

13.2.1 I2C

SCL时钟线 SDA数据线

一个 I2C 总线只使用两条总线线路,一条双向串行数据线(SDA),一 条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。

总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而 当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。

应答:低电平脉冲

非应答:高电平脉冲

13.2.2 AT24C02

根据iic协议实现传输

13.3 小结

模拟的iic协议。大概能理解意思,没太懂这个实验的细节。

十四、DS18B20 温度传感器实验

用传感器采集数据后显示出来,重点在于处理采集到的数据。

传输数据等操作时必须要有拉低DQ后DQ=1的操作。按照硬件的操作要求来。

十五、小结

之后的实验似乎都是连接外设,根据外设的硬件规范编写相应的连接函数再操作,这里就不再写了。

我觉得单片机和平时接触到的不同点在于:它是和硬件一同完成功能的。硬件提供接口,程序捕捉或改变接口的电气性质完成操作。

对电脑是怎样跑起来的多了点儿理解。

蒟蒻初学单片机的一丢丢笔记相关推荐

  1. 196、基于51单片机无线蓝牙防丢器无线寻物报警器手机防丢失APP搜寻设计

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘 要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.PCB图 六.程序源码 七.资料包括 摘 要 在现实生活中,大多数人都曾有过丢失贵重 ...

  2. 蒟蒻的C盘怎么又变红了?(C盘空间快满了怎么清理,AppData,winsxs,Local,Roaming等文件夹如何清理,哪些文件可以删除,哪些属于垃圾)

    关注作者:JuruoAssociation 原创于 CSDN 原创不易,谢绝转载!不曾授权任何转载!建立在抄袭上的流量不会持久.你选择的光,将驱散你身边的黑暗,也将给我们伟大祖国版权事业的未来添一把炬 ...

  3. 蒟蒻的python 学习笔记 ——北京理工大学嵩天mooc(有时间就看就更新,尽量让笔记容易懂,蟹蟹各位大神不吝赐教)

    蒟蒻的python 学习笔记 前言 课一:python语言程序设计 第一周:python 基本语法元素 1.1 程序设计基本方法 1.2 python 环境配置 1.3 实例1:温度转换 1.4 py ...

  4. CCF NOI WC 2019 游记 by.一个云南蒟蒻

    序 我是一个来自云南的蒟蒻. 大约是2018年八月份,我开始正式学习OI.在此之前,我约莫一直听说这世上有这么一种神奇的东西,兴许也曾路过,却从未走进这扇门来(大概是百度过,兴许是被铺天盖地的广告劝退 ...

  5. 本蒟蒻对于二分图一些定理的理解

    本蒟蒻对于二分图一些定理的理解 先给出一些定理 (常识) 1.对于一个无向图 G,若 G 中的所有回路长度均为偶数,则G为一个二分图. 2.二分图的最小点覆盖 = 最大匹配数. 3.二分图的最大独立集 ...

  6. 【bzoj4916】神犇和蒟蒻 杜教筛

    题目描述 很久很久以前,有一只神犇叫yzy; 很久很久之后,有一只蒟蒻叫lty; 输入 请你读入一个整数N;1<=N<=1E9,A.B模1E9+7; 输出 请你输出一个整数A=\sum_{ ...

  7. 蒟蒻浅谈树链剖分之一——两个dfs操作

    树链剖分,顾名思义就是将树形的结构剖分成链,我们以此便于在链上操作 首先我们需要明白在树链剖分中的一些概念 重儿子:某节点所有儿子中子树最多的儿子 重链:有重儿子构成的链 dfs序:按重儿子优先遍历时 ...

  8. python字符串去头尾_悉尼大学某蒟蒻的Python学习笔记

    About me 本蒟蒻是悉尼大学计算机科学大一的学生,这篇博客记录了学习INFO1110这门课的一些心得,希望能对大家有帮助. To start with 因为计算机只能识别机器语言,所以我们需要编 ...

  9. 【BZOJ4916】神犇和蒟蒻(杜教筛)

    [BZOJ4916]神犇和蒟蒻(杜教筛) https://www.cnblogs.com/cjyyb/p/8297338.html 杜教筛技巧

最新文章

  1. OpenVAS漏洞扫描
  2. Android第三十一期 - 市面上所有引导页的效果
  3. 妈妈帮携手神策数据 数据赋能打造母婴智能陪伴者
  4. Grid表格的js触发事件
  5. pyqt5 qlabel无法显示图片_实战PyQt5: 011-单选框控件QRadioButton
  6. PreferenceActivity之 Subclasses of PreferenceActivity must override isValidFragment(String)
  7. 转载:我的外语学习历程(如何学会十门外语)
  8. 高德地图Amap常用功能总结
  9. 早上空腹喝酸奶好吗?
  10. ExcelVBA实现一键生成word文字报告及批量操作[原创]
  11. c语言花样编程,C语言表达式的花样表达
  12. Unix Shell范例精解---grep和sed练习题
  13. P,NP,PSPACE都是什么,一文讲清计算复杂性分类
  14. Charles 抓包,服务器压力测试
  15. 上海调整私车额度参拍条件:申请前一年内无交通违法行为记录
  16. 手动将jar加入到maven仓库
  17. 在Mysql中为什么定义varchar(255)?
  18. 中国PostgreSQL培训认证——特别篇
  19. Linux之RAID介绍、软RAID5实操配置(失望攒够了就放手,不打扰是我最后的温柔)
  20. 《Mybatis实现数据库多表查询》——————多对一

热门文章

  1. 数据结构-排序(六)简单选择排序
  2. Apache mina,Netty的起源和历史
  3. Android 高仿ImageLoader图片加载
  4. sqlalchemy钩子
  5. 虚拟机的网卡提示“网络电缆没有插好”的解决方法
  6. https连接图片显示不出来
  7. 浅谈敏捷开发和迭代开发相结合
  8. 计算机英语司爱侠第二版全文,计算机英语 第2版 配套习题 作者 司爱侠 张强华 参考试卷.doc...
  9. jQuery fade方法
  10. 吴裕雄--天生自然 诗经:江城子·乙卯正月二十日夜记梦