作者:qiushui_007
转自:http://blog.chinaunix.net/uid-27194309-id-3501649.html
点击(此处)折叠或打开
- #include "xustm32.h"
- #include "xucommon.h"
- //#define COM_DEBUG
- #include "xudebug.h"
- //-------------------- STM32通用函数集锦 ---------------------------------------------------
- #if 0
- HardFault_Handler
- PROC
- ; EXPORT HardFault_Handler [WEAK]
- ; B .
- IMPORT hard_fault_handler_c
- TST LR, #4
- ITE EQ
- MRSEQ R0, MSP
- MRSNE R0, PSP
- B hard_fault_handler_c
- ENDP
- #endif
- // hard fault handlerin C, with stack framelocation as input parameter
- void hard_fault_handler_c(unsigned long * hardfault_args)
- {
- unsigned long stacked_r0, stacked_r1, stacked_r2, stacked_r3, stacked_r12, stacked_lr, stacked_pc, stacked_psr;
- stacked_r0 = ((unsigned long) hardfault_args[0]);
- stacked_r1 = ((unsigned long) hardfault_args[1]);
- stacked_r2 = ((unsigned long) hardfault_args[2]);
- stacked_r3 = ((unsigned long) hardfault_args[3]);
- stacked_r12 = ((unsigned long) hardfault_args[4]);
- stacked_lr = ((unsigned long) hardfault_args[5]);
- stacked_pc = ((unsigned long) hardfault_args[6]);
- stacked_psr = ((unsigned long) hardfault_args[7]);
- UARTprintf ("[Hard fault handler]????n");
- UARTprintf ("R0 = %x, R1 = %x, R2 = %x, R3 = %x, R12 = %xn", stacked_r0, stacked_r1, stacked_r2, stacked_r3);
- UARTprintf ("R12 = %x, LR = %x, PC = %x, PSR = %xn", stacked_r12, stacked_lr, stacked_pc, stacked_psr);
- UARTprintf ("BFAR = %xn",(*((volatile unsigned long*)(0xE000ED38))));
- UARTprintf ("CFSR = %xn",(*((volatile unsigned long*)(0xE000ED28))));
- UARTprintf ("HFSR = %xn",(*((volatile unsigned long*)(0xE000ED2C))));
- UARTprintf ("DFSR = %xn",(*((volatile unsigned long*)(0xE000ED30))));
- UARTprintf ("AFSR = %xn",(*((volatile unsigned long*)(0xE000ED3C))));
- #if 0
- Debug ("Now Task : %snr",OSTCBPrioTbl[OSTCBCur->OSTCBPrio]->OSTCBTaskName);
- OS_TaskStkCheck(TRUE);
- OS_DebugHeap();
- Q_ErrorStopScreen("HardFaultException");
- #endif
- while(1){}
- }
- void GetSerialNO(void)
- {
- u32 Dev_Serial0, Dev_Serial1, Dev_Serial2;
- Dev_Serial0 = HWREG(0x1FFFF7E8);
- Dev_Serial1 = HWREG(0x1FFFF7EC);
- Dev_Serial2 = *(vu32*)(0x1FFFF7F0);
- DEBUG_PRINT("SerialNO = %08X %08X %08Xn", Dev_Serial0, Dev_Serial1, Dev_Serial2);
- //SerialNO= 066C0036 33315330 43184129
- }
- //本函数名不可改, uCOS中应用到
- u32 GetClocksFreq(void)
- {
- RCC_ClocksTypeDef rcc_clocks;
- RCC_GetClocksFreq(&rcc_clocks); //获取系统频率
- return(rcc_clocks.HCLK_Frequency);
- }
- //--- 独立看门狗
- void IWDG_Init(unsigned char ucSecond)
- {
- IWDG->KR= 0X5555; //使能对IWDG->PR和IWDG->RLR的写
- IWDG->PR= IWDG_Prescaler_64;//设置分频系数
- IWDG->RLR= 625*ucSecond; //从加载寄存器 IWDG->RLR
- IWDG->KR= 0XAAAA; //reload
- IWDG->KR= 0XCCCC; //使能看门狗
- }
- //THUMB指令不支持汇编内联, 采用如下方法实现执行汇编指令WFI
- __asm void WFI_SET(void)
- {
- WFI;
- }
- //进入待机模式
- void SystemStandby(void)
- {
- SCB->SCR |= 1<<2; //使能SLEEPDEEP位(SYS->CTRL)
- RCC->APB1ENR|= 1<<28; //使能电源时钟
- RCC->APB1ENR|= 1<<27; //使能备份时钟
- PWR->CSR |= 1<<8;//设置WKUP用于唤醒
- PWR->CR |= 1<<2;//清除Wake-up 标志
- PWR->CR |= 1<<1;//PDDS置位
- WFI_SET(); //执行WFI指令
- }
- //--------------------- UART Begin -----------------------------------------------------
- extern COM_TypeDef g_DebugComNo;
- #define EVAL_COM1 USART1
- #define EVAL_COM1_GPIO GPIOA
- #define EVAL_COM1_CLK RCC_APB2Periph_USART1
- #define EVAL_COM1_GPIO_CLK RCC_APB2Periph_GPIOA
- #define EVAL_COM1_RxPin GPIO_Pin_10
- #define EVAL_COM1_TxPin GPIO_Pin_9
- #define EVAL_COM2 USART2
- #define EVAL_COM2_GPIO GPIOA
- #define EVAL_COM2_CLK RCC_APB1Periph_USART2
- #define EVAL_COM2_GPIO_CLK RCC_APB2Periph_GPIOA
- #define EVAL_COM2_RxPin GPIO_Pin_3
- #define EVAL_COM2_TxPin GPIO_Pin_2
- #define COMn 2
- USART_TypeDef* COM_USART[COMn]={EVAL_COM1, EVAL_COM2};
- GPIO_TypeDef* COM_PORT[COMn]={EVAL_COM1_GPIO, EVAL_COM2_GPIO};
- const uint32_t COM_USART_CLK[COMn]={EVAL_COM1_CLK, EVAL_COM2_CLK};
- const uint32_t COM_POR_CLK[COMn]={EVAL_COM1_GPIO_CLK, EVAL_COM2_GPIO_CLK};
- const uint16_t COM_TX_PIN[COMn]={EVAL_COM1_TxPin, EVAL_COM2_TxPin};
- const uint16_t COM_RX_PIN[COMn]={EVAL_COM1_RxPin, EVAL_COM2_RxPin};
- /*typedef enum{
- GPIO_Mode_AIN = 0x0, //模拟输入
- GPIO_Mode_IN_FLOATING = 0x04, //浮空输入模式, 默认
- GPIO_Mode_IPD = 0x28, //上拉/下拉输入模式
- GPIO_Mode_IPU = 0x48, //保留
- GPIO_Mode_Out_OD = 0x14, //通用开漏输出
- GPIO_Mode_Out_PP = 0x10, //通用推挽输出, 无输出.
- GPIO_Mode_AF_OD = 0x1C, //复用(开漏)输出
- GPIO_Mode_AF_PP = 0x18 //复用(推挽)输出. 乱码
- } GPIOMode_TypeDef;*/
- void USART_Set(COM_TypeDef COM, uint32 BaudRate)
- {
- USART_InitTypeDef USART_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitStructure.USART_BaudRate = BaudRate;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- /* Enable GPIO clock*/
- RCC_APB2PeriphClockCmd(COM_POR_CLK[COM]| RCC_APB2Periph_AFIO, ENABLE); //使能串口所有GPIO模块时钟,并使能AFIO模块时钟
- /* Enable UART clock*/
- if (COM== COM1){
- RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE); //使能串口模块时钟
- }
- else {
- RCC_APB1PeriphClockCmd(COM_USART_CLK[COM], ENABLE); //使能串口模块时钟
- }
- /* Configure USART Tx as alternatefunction push-pull*/
- GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[COM]; //设置TX引脚
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(COM_PORT[COM],&GPIO_InitStructure);
- /* Configure USART Rx as input floating*/
- GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM]; //设置RX引脚
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
- GPIO_Init(COM_PORT[COM],&GPIO_InitStructure);
- /* USART configuration*/
- USART_Init(COM_USART[COM],&USART_InitStructure); //初始化USART
- /* Enable USART Receiveand Transmit interrupts*/
- USART_ITConfig(COM_USART[COM], USART_IT_RXNE, ENABLE);
- //USART_ITConfig(COM_USART[COM], USART_IT_TXE, ENABLE);
- /* Enable USART*/
- USART_Cmd(COM_USART[COM], ENABLE); //使能串口模块
- //USART_DMACmd(COM, USART_DMAReq_Rx, ENABLE);//使能UART DAM传输
- }
- void UARTSendChar(COM_TypeDef COM, uint8_t ch)
- {
- /* Loop until the end of transmission */
- //USART_SendData(COM_USART[COM], ch);
- while (USART_GetFlagStatus(COM_USART[COM], USART_FLAG_TC) == RESET);
- USART_SendData(COM_USART[COM], ch);
- }
- void UARTOut(COM_TypeDef COM, uint8_t*Data, uint16_tLen)
- {
- uint16_t i;
- for(i=0; i<Len; i++){
- UARTSendChar(COM, Data[i]);
- }
- }
- //--- used by UARTprintf
- void UARTwrite(const char*pucBuffer, unsigned long ulCount)
- {
- // Loop while there are more characters to send, Write the next character to the UART.
- while(ulCount--){
- if(*pucBuffer=='n'){
- UARTSendChar(g_DebugComNo,'r');
- }
- UARTSendChar(g_DebugComNo,*pucBuffer++);
- }
- }
- #if 0
- #define UARTSOF '$'
- #define UARTEOF 0x0d
- unsigned char RxBuffer1[100];
- unsigned short RxCounter1;
- void USART1_IRQHandler(void)
- {
- unsigned char ucTmp;
- #ifdef RTX_KERNEL
- void *msg;
- #endif
- #ifdef UCOS_KERNEL
- INPUT_EVENT IE;
- OS_IntEnter();
- #endif
- if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
- {
- /* Read one byte from the receive data register*/
- ucTmp = USART_ReceiveData(USART1);
- if (ucTmp== UARTSOF){
- RxCounter1 = 1;
- RxBuffer1[0]= ucTmp;
- }
- else if(ucTmp== UARTEOF){
- /* Disable the USART1 Receive interrupt*/
- //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
- RxBuffer1[RxCounter1]=''; //结束符.
- #ifdef RTX_KERNEL
- msg = malloc(RxCounter1);
- strcpyx((U8*)msg, RxBuffer1);
- isr_mbx_send(COMReceiveMailbox, msg);
- #else
- #ifdef UCOS_KERNEL
- //串口输入事件
- IE.uType = Sync_Type;
- IE.EventType= Input_UartInput;
- IE.Num = 1;//表示串口1
- //IE.Info.SyncInfo.IntParam =((IE.Num<<16)+ RxCounter1);
- IE.Info.SyncInfo.IntParam = RxCounter1;
- IE.Info.SyncInfo.pParam = RxBuffer1;
- OS_MsgBoxSend(gInputHandler_Queue,&IE, 100);
- #else
- UARTprintf("%sn", RxBuffer1);
- #endif
- #endif
- RxCounter1 = 0;
- }
- else if(IS_AF(ucTmp)|| IS_af(ucTmp)|| IS_09(ucTmp)){
- RxBuffer1[RxCounter1++]= ucTmp;
- }
- }
- USART_ClearITPendingBit(USART1, USART_IT_RXNE);//清除中断标志
- #ifdef UCOS_KERNEL
- OS_IntExit();
- #endif
- }
- #endif
- //----------------------------- UART End ------------------------------------------------------------
Flash 读写例程
#define FLASH_ADR 0x08008000 //要写入数据的地址
#define FLASH_DATA 0x01020304 //要写入的数据
#define HWREG(x) (*((volatile unsigned long *)(x)))
tmp = HWREG(FLASH_ADR);
if(tmp == 0xffffffff)
{
FLASH_Unlock();
FLASH_ProgramWord(FLASH_ADR, FLASH_DATA);
FLASH_Lock();
DEBUG_PRINT("要写入的地址为空,已经写入认证数据\n"); //在指定地址编写一个字
}
else if(tmp == FLASH_DATA)
{
DEBUG_PRINT("地址数据与认证数据符合\n");
FLASH_Unlock();
FLASH_ErasePage(FLASH_ADR);
/* 和众多 FLASH 存储器的特性类似,STM32 内的FLASH 数据只能由1变成0,如果要由0变成1,则需要调用刷除函数,
把一个页都刷除掉.如果不擦也能写但是只能写上0*/
FLASH_ProgramWord(FLASH_ADR, 0x11223344);
FLASH_Lock();
DEBUG_PRINT("写入了0x11223344\n");
}
else
{
DEBUG_PRINT("地址上的数据与认证的数据不符合,有可能是写入失败或者是要写入的地址非空\n");
FLASH_Unlock();
FLASH_ErasePage(FLASH_ADR);
FLASH_Lock();
DEBUG_PRINT("已经刷除了要写入的地址\r\n");
}