Study notes | Review (1-12 lessons) | Applying modular programming | Adding function headers | Static variables static | STC32G microcontroller video development tutorial (Brother Chong) | Stage summary: Applying modular programming (Part 1)

1. Review (1-12 lessons)

一、认识单片机
二、了解单片机硬件(介绍开发板)
三、开发环境搭建和下载,新工程建立资料下载
四、点亮点一个LED(CDC和HID下载)		--GPIO
五、C语言运算符和进制数入门
六、LED闪烁和花式点灯       			--GPIO
七、按键点亮灯					--GPIO
八、蜂鸣器					--GPIO
九、数码管的静态使用				--GPIO
十、数码管动态点亮 				--GPIO
十一、定时器					--TIM
十二、计数器的使用				--TIM

Focus on clarifying the logic of the program. Focus on clarifying the logic of the program. Focus on clarifying the logic of the program. When to turn on the LED? How long is the LED on? When to switch the digital tube display? When does a button press trigger what function?
The previous lessons were mainly to familiarize everyone with the method of writing programs, analyze the logic, and realize the functions we want.
So at the beginning of this lesson, we need to standardize the program and comply with our engineer-level code specifications.

2. Apply modular programming (.c + .h)

1. LED & digital tube--led_seg.c, led_seg.h
2. Key--key.c, key.h
3. Buzzer--beep.c, beep.h
4. Timer--tim.c ,
a function of tim.h corresponds to a .c and .h

Tips: Add function header

//================================================== ==========================
// Function name:
// Function function:
// Entry parameter: @
// Function return:
// Current version: VER1.0
// Date Modified: 2023
// Current Author:
// Other Remarks:
//============================== ==============================================
Set in keil:
Insert image description here

Insert image description here
After adding, restart the software and it will be ready for use.

Three steps to create program files

新建文件并保存
添加到工程
添加引用路径

The pin definitions are all in the .h file

sbit 名称 = P10;
#define 名称 P10

Three steps of function definition

定义
声明
调用

The modifier extern is used before the declaration of a variable or function to indicate "this variable/function is defined elsewhere and should be referenced here."
Example 1: If file ac needs to reference the variable int v in bc, you can declare extern int v in ac, and then you can reference the variable v.
Example 2: If the file ac needs to reference the variable int v in bc, you can declare extern int v in bh, and then ac calls bh to reference the variable v.
Note that variables modified by extern cannot be assigned initial values.
For detailed introduction, please refer to: extern keyword, detailed explanation of the usage of extern keyword in C language .

Use of bdata bit-addressed variables

a.c a.h
u8 bdata LED = 0x00; extern u8 bdata LED;
sbit LED0 = LED^0; extern bit LED0;
sbit LED1 = LED^1; extern bit LED1;

3. Compilation of engineering documents

Insert image description here
Insert image description here

Insert image description here
Because they share the P6 port, they are placed in a file.

The previous program refreshed the digital tube through a function in the timer. Now we need to add the function of refreshing the LED. The display is refreshed here, and the value is assigned elsewhere.
Use the files in the previous section and copy them into project 9. TIM multi-task, enter, create a new directory (path) HARDWARE, put all subroutines in it, create 4 folders for the 4 functions to be written this time, and keep them for later use:
Insert image description here
Open the project and select Add New ltem to Group 'source Group 1'…
Insert image description here

You can create new seg_led.c and seg_led.h in the LED directory:
Insert image description here

Add reference path:
Insert image description here

At this point, the project file template is created.
seg_led.h modification, add infdef predefined:

#ifndef __SEG_LED_H
#define __SEG_LED_H

#include "COMM/stc.h"		//调用头文件
#include "COMM/usb.h"

#endif

You can save this predefinition as a template for easy use.
Add calls to seg_led.h in both seg_led.c and demo.c.
Migrate the functions of the digital tube in demo.c to seg_led.c:

u8 SEG_Tab[21] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff};	//共21个字节:0-9段码共10个,0-9带小数点共10个,全部不显示共1个,
u8 COM_Tab[8] = { 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe };																	//0-7的位码数组
u8 Show_Tab[8] = {20,20,20,20,20,20,20,20};

The use of static variables static

If you want to control the variable Show_Tab for display in other files, you need to put it in the .h file as an external variable: extern u8 Show_Tab[8];, and then call it in the main function.
Port the void SEG_Fre(void) function to seg_led.c, and add static variables to the function body. Static variables are only assigned initial values ​​when executed for the first time, defined as: static int num = 0;, and will not be assigned values ​​later.
If you do not add static, it will be reassigned to 0 every time you enter the function, and the value after the second bit will not be refreshed, so you need to use a static variable and assign it only once.
You need to declare it in seg_led.h: void SEG_Fre(void);
delete or comment out the counter initialization part of the original program code in demo.c:

//	TMOD = 0x50;			//设置计数器模式   
//	TL1 = 0x00;				//设置计数初始值
//	TH1 = 0x00;				//设置计数初始值
//	TF1 = 0;				//清除TF1标志
//	TR1 = 1;				//定时器1开始计时
//	ET1 = 1;				//使能定时器1中断
//	    
//	P3PU = 0x20; 			//打开内部上拉4.1K

Delete the redundant code in the main function and leave timer 0 initialized.
Add the digital tube to assign initial values ​​to the main program demo.c file.

	//数码管初始化,显示0-7:
	Show_Tab[0] = 0;
	Show_Tab[1] = 1;
	Show_Tab[2] = 2;
	Show_Tab[3] = 3;
	Show_Tab[4] = 4;
	Show_Tab[5] = 5;
	Show_Tab[6] = 6;
	Show_Tab[7] = 7;

Add pin definition in .h file:

//------------------------引脚定义------------------------//
#define SEG_SEG P6
#define SEG_COM P7
#define LED_POW P40 	//P40是led的电源开关

Compile, select the target file, and the download is completed. The digital tube displays 0-7, but the LED still does not light up. You need to add the corresponding lighting refresh code.
Define the LED display variables and power switch in seg_led.h:

extern u8 LED_DATA;		//LED的显示变量

#define LED_POW P40 	//P40是led的电源开关

Add pin definition:
Update refresh function SEG_Fre in seg_led.c:

void SEG_Fre( void )
{
	static int num = 0;

	if(num <=7 )						//num==0-7的执行
	{
		LED_POW = 0;					//关闭LED电源
		SEG_COM = COM_Tab[num];			//相应数码管位码的选择
		SEG_SEG = SEG_Tab[Show_Tab[num]];//需要显示的数字的内码
	}

	else if ( num <= 8 )				//num==8的执行
	{
		LED_POW = 0;					//LED刷新,打开电源
		SEG_COM = 0xff;					//关闭数码管
		SEG_SEG = LED_DATA;				//输出LED状态
	}
	else								//num==9的执行
	{
		LED_POW = 1;					//LED关闭电源
		SEG_COM = 0xff;					//关闭数码管
		SEG_SEG = 0xff;					//关闭所有段码信号
	}

	num++;
	if( num >=10 )
		num = 0;						//num清零
}

Assign initial value to LED in demo.c:

LED_DATA = 0x0f;	//赋初值,亮一半灭一半

The complete program is:

demo.c:

#include "COMM/stc.h"		//调用头文件
#include "COMM/usb.h"
#include "seg_led.h"

#define KEY1 P32		//定义一个按键 引脚选择P32
#define KEY2 P33		//定义一个按键 引脚选择P33

#define BEEP P54		//定义一个按键 引脚选择P54

#define SEG_Delay  1	//延时多少ms

#define MAIN_Fosc 24000000UL	//定义主时钟

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";


u32 TimCount = 0;		//计数单位1ms
bit RUN_State = 0;		//开始运行/结束运行
u8 num = 0;
u16 Count_T1 = 0;

void sys_init();	//函数声明
//void delay_ms(u16 ms);	//unsigned int
//void INT1_Isr(void);
void Timer0_Isr(void);




void main()					//程序开始运行的入口
{

	sys_init();				//USB功能+IO口初始化
	usb_init();				//usb库初始化

	EA = 1;					//CPU开放中断,打开总中断。

	//数码管初始化,显示0-7:
	Show_Tab[0] = 0;
	Show_Tab[1] = 1;
	Show_Tab[2] = 2;
	Show_Tab[3] = 3;
	Show_Tab[4] = 4;
	Show_Tab[5] = 5;
	Show_Tab[6] = 6;
	Show_Tab[0] = 7;

	LED_DATA = 0x0f;	//赋初值,亮一半灭一半

	while(1)		//死循环
	{
		if( DeviceState != DEVSTATE_CONFIGURED ) 	//
			continue;
		if( bUsbOutReady )
		{
			usb_OUT_done();

		}

	}
}

void sys_init()		//函数定义
{
    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

	P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    P3M0 = 0x00;
    P3M1 = 0x00;

    P3M0 &= ~0x03;
    P3M1 |= 0x03;

    //设置USB使用的时钟源
    IRC48MCR = 0x80;    //使能内部48M高速IRC
    while (!(IRC48MCR & 0x01));  //等待时钟稳定

    USBCLK = 0x00;	//使用CDC功能需要使用这两行,HID功能禁用这两行。
    USBCON = 0x90;
}


//void delay_ms(u16 ms)	//unsigned int
//{
//	u16 i;
//	do
//	{
//		i = MAIN_Fosc/6000;
//		while(--i);
//	}while(--ms);
//}

void Timer0_Isr(void) interrupt 1 //1ms进来执行一次,无需其他延时,重复赋值
{
	SEG_Fre();		//数码管刷新1ms执行一次

}

//void INT1_Isr(void) interrupt 3 //计时器中断
//{
//	//P60 = !P60; //led取反
//}

seg_led.c:

#include "seg_led.h"

u8 SEG_Tab[21] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff};	//共21个字节:0-9段码共10个,0-9带小数点共10个,全部不显示共1个,
u8 COM_Tab[8]  = { 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe };																	//0-7的位码数组
u8 Show_Tab[8] = {20,20,20,20,20,20,20,20}; 																					//数码管显示数组,上电后,全部关闭显示
//u8 LED_DATA  =  0xff;																											//LED初始全部熄灭

void SEG_Fre( void )
{
	static int num = 0;

	if(num <=7 )						//num==0-7的执行
	{
		LED_POW = 0;					//关闭LED电源
		SEG_COM = COM_Tab[num];			//相应数码管位码的选择
		SEG_SEG = SEG_Tab[Show_Tab[num]];//需要显示的数字的内码
	}

	else if ( num <= 8 )				//num==8的执行
	{
		LED_POW = 0;					//LED刷新,打开电源
		SEG_COM = 0xff;					//关闭数码管
		SEG_SEG = LED_DATA;				//输出LED状态
	}
	else								//num==9的执行
	{
		LED_POW = 1;					//LED关闭电源
		SEG_COM = 0xff;					//关闭数码管
		SEG_SEG = 0xff;					//关闭所有段码信号
	}

	num++;
	if( num >=10 )
		num = 0;						//num清零
}

seg_led.h:

#ifndef __SEG_LED_H
#define __SEG_LED_H

#include "COMM/stc.h"		//调用头文件
#include "COMM/usb.h"

extern u8 Show_Tab[8];		//数码管的内码显示变量
extern u8 LED_DATA;		//LED的显示变量


//------------------------引脚定义------------------------//
#define SEG_SEG P6
#define SEG_COM P7
#define LED_POW P40 	//P40是led的电源开关

void SEG_Fre(void);  		//仅声明

#endif

Guess you like

Origin blog.csdn.net/Medlar_CN/article/details/132733915