【MM32芯片学习】MM32F0131系列单片机IAP跳转程序死机问题

首先看BOOT代码程序跳转部分部分

//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{
	if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//检查栈顶地址是否合法.
	{ 
		JumpAddress = *(__IO uint32_t *)(appxaddr + 4);// jump2app=(iapfun)*(vu32*)(appxaddr+4);		//用户代码区第二个字为程序开始地址(复位地址)		
		jump2app = (iapfun)JumpAddress;
		__set_MSP(*(volatile uint32_t*)appxaddr);//MSR_MSP(*(vu32*)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址   (__IO uint32_t *)
		jump2app();									//跳转到APP.
	}
}		 

    因为mm32f0131是M0内核的单片机目前的库函数中没有SCB->VTOR这个中断向量表重定义的寄存器于是我们可以通过以下方法来实现中断向量表重定义。

基本思想:

1、将中断向量表放入到RAM的起始地址(只需要在应用程序中保留RAM起始地址的0x100大小不使用即可)。

2、在Bootloader中将应用程序的中断向量表从Flash中拷贝到RAM中。

3、设置MM32F013中断向量表位于RAM中

在APP的程序中添加如下代码

	    

        #define APP_START_ADDRESS (uint32_t)(0x8008000)
main()
{
        memcpy((uint8_t *)SRAM_BASE, (uint8_t *)APP_START_ADDRESS, 48*4);	//这里复制中断向量表
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);			
		SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM); 	

.
.
.
.
.
}

我这里把flash的起始地址设为0x8008000,可以根据需要进行修改   要注意的是   48*4  是因为我使用的该款单片机有48个中断向量每个向量4个字节   不同的单片机可能存在不同。

在app程序中设置地址

0x8008000设置是因为我app的flash起始地址是这个

0x20000C0的设置是因为我使用的该款单片机有48个中断向量*4即为C0

BOOT部分原码:https://download.csdn.net/download/qxw0923/19823759?spm=1001.2014.3001.5501

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是基于MM32F0010A单片机的tm1624驱动程序示例代码: ``` #include "MM32F0010.h" #define SDA_PORT GPIOA #define SDA_PIN GPIO_Pin_5 #define SCL_PORT GPIOA #define SCL_PIN GPIO_Pin_6 #define TM1624_CMD1 0x8a #define TM1624_CMD2 0x40 void TM1624_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = SDA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(SDA_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = SCL_PIN; GPIO_Init(SCL_PORT, &GPIO_InitStructure); } void TM1624_SendByte(uint8_t data) { uint8_t i; for (i = 0; i < 8; i++) { if (data & 0x80) GPIO_SetBits(SDA_PORT, SDA_PIN); else GPIO_ResetBits(SDA_PORT, SDA_PIN); data <<= 1; GPIO_SetBits(SCL_PORT, SCL_PIN); GPIO_ResetBits(SCL_PORT, SCL_PIN); } } void TM1624_WriteCmd(uint8_t cmd) { GPIO_ResetBits(SCL_PORT, SCL_PIN); GPIO_ResetBits(SDA_PORT, SDA_PIN); TM1624_SendByte(cmd); GPIO_SetBits(SCL_PORT, SCL_PIN); } void TM1624_WriteData(uint8_t address, uint8_t data) { TM1624_WriteCmd(TM1624_CMD1); TM1624_WriteCmd(address << 1); TM1624_WriteCmd(data); } void TM1624_Clear(void) { uint8_t i; TM1624_WriteCmd(TM1624_CMD1); TM1624_WriteCmd(0x00); for (i = 0; i < 16; i++) TM1624_WriteData(i, 0x00); } int main(void) { TM1624_Init(); TM1624_Clear(); TM1624_WriteData(0, 0x01); TM1624_WriteData(1, 0x02); TM1624_WriteData(2, 0x03); TM1624_WriteData(3, 0x04); while (1) { } } ``` 该代码实现了对tm1624的初始化、发送字节、写入命令和数据、清屏等操作。需要注意的是,SDA和SCL的引脚需要根据实际连接进行修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值