• 蒟蒻初学单片机的一丢丢笔记


    零、引脚

    • 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); //大约延时 4500ms
    		LED1=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();
    		}
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    二、蜂鸣

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

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

    		while (i --){
    			BEEP = !BEEP;
    			delay_10us();
    		} 
    		i = 0;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三、静态显示

    将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)
    	{
    
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    四、动态数码管

    似乎只能把三个引脚设为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();
    	}		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    五、独立按键

    按键被按时被按的变为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状态翻转	
    	}		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    六、矩阵按键

    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,列全为1
    	if (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);//等待按键松开	
    		}
    	}
    	else
    		key_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段码		
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    七、IO 扩展

    右上角的点阵

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

    最下面是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	
    		}									
    	}		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    八、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); //行							
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    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);//消影	
    		}								
    	}		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    /**************************************************************************************
    深圳市普中科技有限公司(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);			
    		}
    							
    	}		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

    九、直流电机

    /**************************************************************************************
    深圳市普中科技有限公司(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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    十、步进电机

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

    五条线: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~7
    				   dir:方向选择,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);						
    	}		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162

    十一、中断

    有点像操作系统里面的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状态翻转					
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    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模式,工作方式1
    	TH0=0XFC;	//给定时器赋初值,定时1ms
    	TL0=0X18;	
    	ET0=1;//打开定时器0中断允许
    	EA=1;//打开总中断
    	TR0=1;//打开定时器		
    }
    
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {	
    	time0_init();//定时器0中断配置
    
    	while(1)
    	{			
    							
    	}		
    }
    
    void time0() interrupt 1 //定时器0中断函数
    {
    	static u16 i;//定义静态变量i
    	TH0=0XFC;	//给定时器赋初值,定时1ms
    	TL0=0X18;
    	i++;
    	if(i==1000)
    	{
    		i=0;
    		LED1=!LED1;	
    	}						
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    十二、串口通信

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

    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;	//设置计数器工作方式2
    	SCON=0X50;	//设置为工作方式1
    	PCON=0X80;	//波特率加倍
    	TH1=baud;	//计数器初始值设置	   
    	TL1=baud;
    	ES=1;		//打开接收中断
    	EA=1;		//打开总中断
    	TR1=1;		//打开计数器		
    }
    
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {	
    	uart_init(0XFA);//波特率为9600
    
    	while(1)
    	{			
    							
    	}		
    }
    
    void uart() interrupt 4 //串口通信中断函数
    {
    	u16 rec_data;
    
    	RI = 0;			//清除接收中断标志位
    	rec_data=SBUF;	//存储接收到的数据
    	SBUF=rec_data;	//将接收到的数据放入到发送寄存器
    	while(!TI);		//等待发送数据完成
    	TI=0;			//清除发送完成标志位				
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

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

    十三、I2C-EEPROM 实验

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

    13.1 项目总览

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

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

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

    功能名称功能
    key按键检测
    smg数码管显示
    iicI2C 读写字节
    24c02AT24C02 读写字节

    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的操作。按照硬件的操作要求来。

    十五、小结

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

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

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

  • 相关阅读:
    Kratos战神微服务框架(二)
    Vue中引入一个异步组件
    Java反射获取抽象类方法属性问题讲解
    我的创作纪念日
    推荐系统[八]算法实践总结V2:排序学习框架(特征提取标签获取方式)以及京东推荐算法精排技术实战
    VauditDemo靶场代码审计
    如何戒掉短视频?2个方法适合职场人,从未失败过
    c++视觉处理---cv::Sobel()`算子
    Tkinter 转载 (来自C语言中文网)
    Singleton、Scoped、Transient 的应用情景有哪些
  • 原文地址:https://blog.csdn.net/weixin_51368613/article/details/125426006