嵌入式第四章作业

1、学习CH04示例程序,包括gpio.c和4个工程中的main.c。

main.c代码

#define GLOBLE_VAR
#include "includes.h"      //包含总头文件

int main(void)
{
	uint32_t mMainLoopCount;  
	uint8_t  mFlag;           
	uint32_t mLightCount;     

	DISABLE_INTERRUPTS;

    mMainLoopCount=0;    
	mFlag='A';           
	mLightCount=0;       
    
	ENABLE_INTERRUPTS;
    printf("------------------------------------------------------\n"); 
    
	for(;;)   
	{

        mMainLoopCount++;

		if (mMainLoopCount<=12888999)  continue;

		mMainLoopCount=0; 

		if (mFlag=='L')                    
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='A';                       
			gpio_set(LIGHT_BLUE,LIGHT_ON);  
			printf(" LIGHT_BLUE:ON--\n");   
		}

		else
		{
			mFlag='L';                       
			gpio_set(LIGHT_BLUE,LIGHT_OFF); 
			printf(" LIGHT_BLUE:OFF--\n");  
		}
	}  

}   

学习到的点

  • DISABLE_INTERRUPTS 和 ENABLE_INTERRUPTS:禁用和启用中断是嵌入式系统编程中的常见做法,用于保护关键代码段,防止在执行过程中被打断。这可以提高代码执行的原子性和一致性。
  • for(;;) 无限循环和计数器 mMainLoopCount 用于实现延时:使用简单的计数器来实现延时控制,是一种常见的时间控制方法。这里通过计数器达到一定值后才执行特定操作,使得程序有节奏地执行任务。
  • if-else 判断 mFlag 的状态,实现简单的状态机:使用标志位 mFlag 控制灯的开关状态,可以看作是一个基本的有限状态机(Finite State Machine,FSM),用于管理系统的状态和行为。
  • 在关键操作(如变量初始化)前后禁用和启用中断:确保在对共享资源(如全局变量)进行操作时不会被中断打断,从而避免数据不一致和其他并发问题。

2、给出  gpio_set(LIGHT_RED,LIGHT_OFF); 语句中, LIGHT_RED和LIGHT_OFF的值是多少?贴出每一步的查找截图。

 3、用直接地址编程方式,实现红绿蓝三灯轮流闪烁

//Uart部分用直接地址方式实现

#define GLOBLE_VAR

#include "includes.h"      //Include the master header file

int main(void)
{   
    //uart register related addresses
    volatile uint32_t* RCC_AHB2;     //Address of GPIO port A clock enable register
    volatile uint32_t* RCC_APB1;     //Address of UART 2 clock enable register
    volatile uint32_t* gpio_ptr;     //Base address of GPIO port A
    volatile uint32_t* uart_ptr;     //Base address of UART 2 port
    volatile uint32_t* gpio_mode;    //Pin mode register address = port base address
    volatile uint32_t* gpio_afrl;    //GPIO alternate function low register
    volatile uint32_t* uart_brr;     //UART baud rate register address
    volatile uint32_t* uart_isr;     //UART interrupt and status register base address
    volatile uint32_t* uart_cr1;     //UART control register 1 base address
    volatile uint32_t* uart_cr2;     //UART control register 2 base address
    volatile uint32_t* uart_cr3;     //UART control register 3 base address
    volatile uint32_t* uart_tdr;     //UART transmit data register
    uint16_t usartdiv;   //Value to be assigned to BRR register

    //Variable assignment
    RCC_APB1=0x40021058UL;   //UART clock enable register address
    RCC_AHB2=0x4002104CUL;   //Address of GPIO port A clock enable register
    gpio_ptr=0x48000000UL;   //Base address of GPIOA port
    uart_ptr=0x40004400UL;  //Base address of UART2 port
    gpio_mode=0x48000000UL;              //Pin mode register address = port base address
    gpio_afrl=0x48000020UL;           // GPIO alternate function low register
    uart_cr1=0x40004400UL;              //UART control register 1 base address
    uart_brr=0x4000440CUL;          // UART baud rate register address
    uart_isr=0x4000441CUL;         // UART interrupt and status register base address
    uart_tdr=0x40004428UL;         //UART transmit data register
    uart_cr2=0x40004404UL;      // UART control register 2 base address
    uart_cr3=0x40004408UL;      //UART control register 3 base address

    //Disable all interrupts
    DISABLE_INTERRUPTS;

    //User peripheral module initialization
    gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF); //Initialize red LED
    gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF); //Initialize green LED
    gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF); //Initialize blue LED

    //uart_init(UART_User,115200); (lines 58-102)

    //Enable GPIOA and UART2 clocks
    *RCC_APB1|=(0x1UL<<17U);       //UART2 clock enable
    *RCC_AHB2 |=(0x1UL<<0U);       //GPIOA clock enable

    //Set GPIO port to alternate function
    //First, clear D7, D6, D5, D4
    *gpio_mode &= ~((0x3UL<<4U)|(0x3UL<<6U));
    //Then set D7, D6, D5, D4 to 1010, setting PTA2, PTA3 to alternate function serial function.
    *gpio_mode |=((0x2UL<<4U)|(0x2UL<<6U));

    //Select pin port alternate function
    //First, clear D15~D8
    *gpio_afrl &= ~((0xFUL<<8U)|(0xFUL<<12U));
    //Then set D15~D8 to 01110111, set PTA3, PTA2 pins to USART2_RX, USART2_TX respectively
    *gpio_afrl=(((0x1UL<<8U)|(0x2UL<<8U)|(0x4UL<<8U))|((0x1UL<<12U)|(0x2UL<<12U)|(0x4UL<<12U)));         

    //Temporarily disable UART functionality, the UE-USART enable bit is at position 0 in control register 1.
    //After clearing this bit, the USART prescaler and output will immediately stop and discard all current operations.
    *uart_cr1 &= ~(0x1UL);

    //Temporarily disable serial transmission and reception, control register 1's transmitter enable bit (D3), receiver enable bit (D2)
    *uart_cr1 &= ~((0x1UL<<3U)|(0x1UL<<2U));

    //Configure baud rate
    if(*uart_cr1&(0x1UL<<15) == (0x1UL<<15))             
        usartdiv = (uint16_t)((SystemCoreClock/115200)*2);
    else
        usartdiv = (uint16_t)((SystemCoreClock/115200));
    *uart_brr = usartdiv;

    //Initialize control register and interrupt status register, clear flags
    //Disable interrupts
    *uart_isr = 0x0UL;    
    //Clear the two enable bits in control register 2. D14-LIN mode enable bit, D11-clock enable bit
    *uart_cr2 &= ~((0x1UL<<14U)|(0x1UL<<11U));
    //Clear the three enable bits in control register 3. D5 (SCEN) -smartcard mode enable bit, 
    //D3 (HDSEL) -half-duplex select bit, D1 (IREN) -IrDA mode enable bit
    *uart_cr3 &= ~((0x1UL<<5U) | (0x1UL<<3U) |(0x1UL<<1U));

    //Start serial transmission and reception
    *uart_cr1 |= ((0x1UL<<3U)|(0x1UL<<2U));

    //Enable UART functionality
    *uart_cr1 |= (0x1UL<<0U);

    //Enable module interrupts
    //uart_enable_re_int(UART_User);  Enable UART_User module receive interrupt function
    //uart_enable_re_int() function implementation: ①Enable UART receive interrupt; ②Enable interrupt controller IRQ interrupt
    *uart_cr1 |= (0x1UL<<5); //Set bit RXNEIE at position 5 in USART_CR1 register: generate USART interrupt when ORE=1 or RXNE=1 in USART_ISR register
    NVIC_EnableIRQ(USART2_IRQn); //Enable interrupt controller USART2 interrupt
    //Enable all interrupts
    ENABLE_INTERRUPTS;

    //Output a prompt to open the serial port tool on the serial update page
    printf("Uart部分用直接地址方式实现\r\n");
}

4、用调用构件方式,实现红绿蓝的八种组合轮流闪烁

#define GLOBLE_VAR
#include "includes.h"      
 
int main(void)
{
	uint32_t mMainLoopCount;  
	uint8_t  mFlag;          
	uint32_t mLightCount;     
 
	DISABLE_INTERRUPTS;
 
    mMainLoopCount=0;    
	mFlag='B';           
	mLightCount=0;       
 
	gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_ON);	//初始化红灯
	
	ENABLE_INTERRUPTS;
	
    printf("------------------------------------------------------\n"); 
    
	for(;;)   
	{
        mMainLoopCount++;
		if (mMainLoopCount<=12888999)  continue;
		mMainLoopCount=0; 
		if (mFlag=='R')                  
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='G';                       
			gpio_set(LIGHT_RED,LIGHT_ON);  
			printf("标志为R  LIGHT_RED=%d ,LIGHT_ON = %d\n",LIGHT_RED,LIGHT_ON);
			printf(" 红灯:ON--\n\n"); 
		}
		else if (mFlag=='G')                    
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='B';                       
			gpio_set(LIGHT_RED,LIGHT_OFF);  
			gpio_set(LIGHT_GREEN,LIGHT_ON);  
			printf("标志为G  LIGHT_GREEN=%d ,LIGHT_ON = %d\n",LIGHT_GREEN,LIGHT_ON);
			printf(" 绿灯:ON--\n\n");   
		}
		else if (mFlag=='B')                    
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='Y';  
			gpio_set(LIGHT_GREEN,LIGHT_OFF);  
			gpio_set(LIGHT_BLUE,LIGHT_ON); 
			gpio_set(LIGHT_RED,LIGHT_OFF);  
			printf("标志为B  LIGHT_BLUE=%d ,LIGHT_ON = %d\n",LIGHT_BLUE,LIGHT_ON);
			printf(" 蓝灯:ON--\n\n");  
		}
		else if (mFlag=='Y')                    
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='P';                       
			gpio_set(LIGHT_RED,LIGHT_ON);  
			gpio_set(LIGHT_BLUE,LIGHT_OFF);  
			gpio_set(LIGHT_GREEN,LIGHT_ON);  
			printf(" 黄灯:ON--\n\n"); 
		}
		else if (mFlag=='P')                    
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='C';                
			gpio_set(LIGHT_RED,LIGHT_ON); 
			gpio_set(LIGHT_GREEN,LIGHT_OFF);
			gpio_set(LIGHT_BLUE,LIGHT_ON);   
			printf(" 紫灯:ON--\n\n"); 
		}
		else if (mFlag=='C')                   
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='W';                       
			gpio_set(LIGHT_BLUE,LIGHT_ON);   
			gpio_set(LIGHT_RED,LIGHT_OFF);
			gpio_set(LIGHT_GREEN,LIGHT_ON);
			printf(" 青灯:ON--\n\n");  
		}
		else if (mFlag=='W')                   
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='D';                      
			gpio_set(LIGHT_BLUE,LIGHT_ON);   
			gpio_set(LIGHT_GREEN,LIGHT_ON);
			gpio_set(LIGHT_RED,LIGHT_ON);  
			printf(" 白灯:ON--\n\n");   
		}
		else if (mFlag=='D')                    
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='R';                      
			gpio_set(LIGHT_GREEN,LIGHT_OFF);
			gpio_set(LIGHT_BLUE,LIGHT_OFF); 
			gpio_set(LIGHT_RED,LIGHT_OFF);  
			printf(" 暗灯:ON--\n\n");   
		}
	}  
}   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值