第六章 作业

1、编写UART_2串口发送程序时,初始化需要设置哪些参数?

(1)确定MCU串口号、所接MCU的引脚;采用的串口为UART_2(编程默认使用UART_User)

(2)确定串口UART_User的波特率,并对其进行初始化

(3)调用uart_send1接口函数发送数据

2、假设速度为115200,系统时钟为72MHz,波特率寄存器 BRR中的值应该是多少?

若 USART_CR1中的第15位的过采样模式为0,则结果为625;

若 USART_CR1中的第15位的过采样模式为1,则结果为1250;

3、中断向量表在哪个文件中?表中有多少项?给出部分截图

中断向量表位于03_MCU/startup/startup_stm32|431rctx.s 

4、以下是中断源使能函数,假设中断源为TIM6,将函数实例化(写出各项具体数值)

TIM6接S收中断的IRQ号为54;

(((uint32_t)IRQn) >> 5UL)将IRQ号58右移5位的结果为1

1UL << (((uint32_t)IRQn) & 0x1FUL)操作为将1左移IRQ号对应前5位的值,结果为22;

即将ISER[1]的第22位设置为1

5、假设将UART_2和TIM6交换其在中断向量表中的位置和IRQ号,UART_2可以正常中断吗?

将 UART_2 和 TIM6 在中断向量表中的位置和 IRQ 号交换后。UART_2 的中断号变为 54,TIM6 的中断号变为 38;这种情况下,UART_2获得了新的中断向量和IRQ号,只要确保在代码中正确配置了新的中断向量和IRQ号,UART_2仍然可以正常中断。TIM6也同样可以正常中断,因为它获得了UART_2原先的中断向量和IRQ号,只要对TIM6重新配置以适应其新的中断向量和IRQ号即可;因为中断号的改变并不影响中断控制器 NVIC 的配置,只是改变了中断向量表中的中断函数入口地址。

6.实现UART_2串口的接收程序

(1) 用构件调用方式实现

#define GLOBLE_VAR
#include "includes.h"      //包含总头文件
int main(void)
{

	uint32_t mMainLoopCount;  //主循环次数变量
	uint8_t  ch;             //临时变量
	uint8_t  flag;             //临时变量

//(1.2)【不变】关总中断
	DISABLE_INTERRUPTS;

//(1.3)给主函数使用的局部变量赋初值
    mMainLoopCount=0;    //主循环次数变量
  
//(1.4)给全局变量赋初值

//(1.5)用户外设模块初始化
	gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF);	//初始化蓝灯
	gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF);	//初始化绿灯
	gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);	    //初始化红灯
	uart_init(UART_User,115200);                    //初始化串口模块   
  
//(1.6)使能模块中断


//(1.7)【不变】开总中断
	ENABLE_INTERRUPTS;
	
  
//(1)======启动部分(结尾)==========================================

//(2)======主循环部分(开头)========================================
	for(;;)   //for(;;)(开头)
	{
		mMainLoopCount++;
		if (mMainLoopCount<=35000000)  continue;
		mMainLoopCount=0;    //循环次数变量
//(2.3.3)通过调试串口提示
        printf("金葫芦友情提示:\r\n");
       // printf("蓝灯亮暗次数=%d,  关闭本窗体\r\n",mLightCount);
        printf("“工具”→“串口工具”,打开接收User串口数据观察\r\n");

        ch = uart_re1(UART_User,&flag);

//若接收到字符flag为1,未接收到则为0
if(flag){
    //收到字符时的处理
    switch(ch){
            case 'G': 
            gpio_set(LIGHT_RED,LIGHT_OFF);   // 关闭红灯
            gpio_set(LIGHT_BLUE,LIGHT_OFF);  // 关闭蓝灯
            gpio_set(LIGHT_GREEN,LIGHT_ON);   //亮绿灯
           
            break;
            case 'R':
            gpio_set(LIGHT_GREEN,LIGHT_OFF);  // 关闭绿灯
            gpio_set(LIGHT_BLUE,LIGHT_OFF);   // 关闭蓝灯
            gpio_set(LIGHT_RED,LIGHT_ON);    // 亮红灯
            
            break;
            case 'B':
            gpio_set(LIGHT_RED,LIGHT_OFF);   // 关闭红灯
            gpio_set(LIGHT_GREEN,LIGHT_OFF); // 关闭绿灯
            gpio_set(LIGHT_BLUE,LIGHT_ON);   // 亮蓝灯
           
            break;
            default:
            gpio_set(LIGHT_RED,LIGHT_OFF);   // 关闭红灯
            gpio_set(LIGHT_GREEN,LIGHT_OFF); // 关闭绿灯
            gpio_set(LIGHT_BLUE,LIGHT_OFF);  // 关闭蓝灯
     
            break;                  
    }
    printf("%c\n",ch+1);
  }

}  
	


}   //main函数(结尾)

(2) UART部分用直接地址方式实现(即不调用uart.c中的函数,其他部分如GPIO、中断设置可调用函数)

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



//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
int main(void)
{
    //(1)======启动部分(开头)==========================================
    //(1.1)声明main函数使用的局部变量
    uint8_t  mTest;
    uint32_t mMainLoopCount;
    uint8_t  ch;             //临时变量
	
    //uart寄存器相关地址
    volatile uint32_t* RCC_AHB2;     //GPIO的A口时钟使能寄存器地址
    volatile uint32_t* RCC_APB1;     //UART的2口时钟使能寄存器地址
    volatile uint32_t* gpio_ptr;       //GPIO的A口基地址
    volatile uint32_t* uart_ptr;       //uart2端口的基地址
    volatile uint32_t* gpio_mode;    //引脚模式寄存器地址=口基地址
    volatile uint32_t* gpio_afrl;      //GPIO复用功能低位寄存器
    volatile uint32_t* uart_brr;      //UART波特率寄存器地址
    volatile uint32_t* uart_isr;      // UART中断和状态寄存器基地址
    volatile uint32_t* uart_cr1;      //UART控制寄存器1基地址 
    volatile uint32_t* uart_cr2;      // UART控制寄存器2基地址
    volatile uint32_t* uart_cr3;      // UART控制寄存器3基地址
    volatile uint32_t* uart_tdr;      // UART发送数据寄存器
    volatile uint32_t* uart_rdr;      // UART接收数据寄存器
    uint16_t usartdiv;   //BRR寄存器应赋的值
    
    //变量赋值
    
    RCC_APB1=0x40021058UL;   //UART时钟使能寄存器地址
    RCC_AHB2=0x4002104CUL;   //GPIO的A口时钟使能寄存器地址
    gpio_ptr=0x48000000UL;   //GPIOA端口的基地址
    uart_ptr=0x40004400UL;  //UART2端口的基地址
    gpio_mode=0x48000000UL;              //引脚模式寄存器地址=口基地址
    gpio_afrl=0x48000020UL;           // GPIO复用功能低位寄存器
    uart_cr1=0x40004400UL;              //UART控制寄存器1基地址 
    uart_brr=0x4000440CUL;          // UART波特率寄存器地址
    uart_isr=0x4000441CUL;         // UART中断和状态寄存器基地址
    uart_tdr=0x40004428UL;         //UART发送数据寄存器
    
    uart_rdr=0x40004424UL;         //UART接收数据寄存器
    
    uart_cr2=0x40004404UL;      // UART控制寄存器2基地址
    uart_cr3=0x40004408UL;      //UART控制寄存器3基地址
    
    //(1.2)【不变】关总中断
    DISABLE_INTERRUPTS;
    
    //(1.3)给主函数使用的局部变量赋初值
    mMainLoopCount=0;
    //(1.4)给全局变量赋初值
    
    //(1.5)用户外设模块初始化
    gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF);	//初始化蓝灯
	gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF);	//初始化绿灯
	gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);	//初始化红灯
    //uart_init(UART_User,115200);
    
    //使能GPIOA和UART2的时钟
    *RCC_APB1|=(0x1UL<<17U);       //UART2时钟使能 
    *RCC_AHB2 |=(0x1UL<<0U);       //GPIOA时钟使能
    
    //将GPIO端口设置为复用功能
    //首先将D7、D6、D5、D4清零
    *gpio_mode &= ~((0x3UL<<4U)|(0x3UL<<6U)); 
    //然后将D7、D6、D5、D4设为1010,设置PTA2、PTA3为复用功能串行功能。
    *gpio_mode |=((0x2UL<<4U)|(0x2UL<<6U));
    
    //选择引脚的端口复用功能
    //首先将D15~D8清零
    *gpio_afrl &= ~((0xFUL<<8U)|(0xFUL<<12U));
    //然后将D15~D8设置为01110111,分别将PTA3、PTA2引脚设置为USART2_RX、USART2_TX 
    *gpio_afrl=(((0x1UL<<8U)|(0x2UL<<8U)|(0x4UL<<8U))|((0x1UL<<12U)
    |(0x2UL<<12U)|(0x4UL<<12U)));         
    
    //暂时禁用UART功能,控制寄存器1的第0位对应的是UE—USART使能位。
    //此位清零后,USART预分频器和输出将立即停止,并丢弃所有当前操作。
    *uart_cr1 &= ~(0x1UL);
    
    //暂时关闭串口发送与接收功能,控制寄存器1的发送器使能位(D3)、接收器使能位(D2)
    *uart_cr1 &= ~((0x1UL<<3U)|(0x1UL<<2U));
    
    //配置波特率
    if(*uart_cr1&(0x1UL<<15) == (0x1UL<<15))             
    usartdiv = (uint16_t)((SystemCoreClock/115200)*2);
    else
    usartdiv = (uint16_t)((SystemCoreClock/115200));
    *uart_brr = usartdiv;
    
    //初始化控制寄存器和中断状态寄存器、清标志位
    //关中断
    *uart_isr = 0x0UL;    
    //将控制寄存器2的两个使能位清零。D14—LIN模式使能位、D11—时钟使能位 
    *uart_cr2 &= ~((0x1UL<<14U)|(0x1UL<<11U));
    //将控制寄存器3的三个使能位清零。D5 (SCEN) —smartcard模式使能位、
    //D3 (HDSEL) —半双工选择位、D1 (IREN) —IrDA 模式使能位
    *uart_cr3 &= ~((0x1UL<<5U) | (0x1UL<<3U) |(0x1UL<<1U));
    
    //启动串口发送与接收功能
    *uart_cr1 |= ((0x1UL<<3U)|(0x1UL<<2U)); 
    
    //开启UART功能
    *uart_cr1 |= (0x1UL<<0U); 
    
    //(1.6)使能模块中断
    uart_enable_re_int(UART_User);  //使能UART_User模块接收中断功能
    //(1.7)【不变】开总中断
    ENABLE_INTERRUPTS;
    
    
    
for(;;)
{
    // 判断接收缓冲区是否满,接受字符
     if (*uart_isr & (0x1UL << 5U)) {
        // 读取接收到的字符
        ch = (uint8_t)(*uart_rdr & 0xFF);
        //接收到字符时的处理
        switch (ch) {
            case 'G':
                gpio_set(LIGHT_RED, LIGHT_OFF);    // 关闭红灯
                gpio_set(LIGHT_BLUE, LIGHT_OFF);   // 关闭蓝灯
                gpio_set(LIGHT_GREEN, LIGHT_ON);  // 亮绿灯
                break;
            case 'R':
                gpio_set(LIGHT_GREEN, LIGHT_OFF);  // 关闭绿灯
                gpio_set(LIGHT_BLUE, LIGHT_OFF);   // 关闭蓝灯
                gpio_set(LIGHT_RED, LIGHT_ON);    // 亮红灯
                break;
            case 'B':
                gpio_set(LIGHT_RED, LIGHT_OFF);    // 关闭红灯
                gpio_set(LIGHT_GREEN, LIGHT_OFF);  // 关闭绿灯
                gpio_set(LIGHT_BLUE, LIGHT_ON);   // 亮蓝灯
                break;
            default:
                // 不亮灯
                gpio_set(LIGHT_RED, LIGHT_OFF);
                gpio_set(LIGHT_GREEN, LIGHT_OFF);
                gpio_set(LIGHT_BLUE, LIGHT_OFF);
                break;
            }
             printf("%c\n",ch+1);
             
        }

} 
    
   
}  

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
xjtu计组第六章作业主要涉及计算机组成原理的相关概念和知识点。这一章节主要包括存储器的层次结构、存储器的组织和管理、存储器的屏蔽、存储器的操作和传输等内容。 首先,存储器的层次结构是计算机中非常重要的一个组成部分。它包括寄存器、高速缓存、主存和辅助存储器等。每一层的存储器容量和速度不同,寄存器最小而速度最快,辅助存储器容量最大但速度最慢。 其次,存储器的组织和管理也是我们需要了解的内容。存储器的组织有两种方式,分别是按地址方式和按内容方式组织。在存储器的管理中,我们需要学习如何管理地址空间、如何进行地址转换和管理内存映射等。 另外,存储器的屏蔽是实现存储器的一种方式。比如,在32位计算机中,通过屏蔽将地址划分为子地址、块地址和字地址,以实现对存储器的访问。 最后,我们还需要了解存储器的操作和传输。存储器的操作包括读取数据和写入数据两个过程,而存储器的传输是指数据在存储器之间的传输。我们需要学习存储器的读写操作的过程、存储器传输的方式以及优化存储器传输的方法。 总的来说,xjtu计组第六章作业涵盖的内容较为广泛,包括存储器的层次结构、组织和管理、屏蔽以及操作和传输等方面。通过完成这份作业,我们可以更好地理解和掌握计算机组成原理这门课程的核心概念和知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值