Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1514603
  • 博文数量: 129
  • 博客积分: 1449
  • 博客等级: 上尉
  • 技术积分: 3048
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-24 18:36
文章分类

全部博文(129)

文章存档

2015年(3)

2014年(20)

2013年(65)

2012年(41)

分类: C/C++

2013-02-27 09:40:04


点击(此处)折叠或打开

  1. #include "xustm32.h"
  2. #include "xucommon.h"

  3. //#define COM_DEBUG
  4. #include "xudebug.h"

  5. //-------------------- STM32通用函数集锦 ---------------------------------------------------
  6. #if 0
  7. HardFault_Handler
  8.                 PROC
  9. ; EXPORT HardFault_Handler [WEAK]
  10. ; B .
  11.                 IMPORT hard_fault_handler_c
  12.                 TST LR, #4
  13.                 ITE EQ
  14.                 MRSEQ R0, MSP
  15.                 MRSNE R0, PSP
  16.                 B hard_fault_handler_c
  17.                 ENDP
  18. #endif
  19. // hard fault handler in C, with stack frame location as input parameter
  20. void hard_fault_handler_c(unsigned long * hardfault_args)
  21. {
  22.   unsigned long stacked_r0, stacked_r1, stacked_r2, stacked_r3, stacked_r12, stacked_lr, stacked_pc, stacked_psr;

  23.   stacked_r0 = ((unsigned long) hardfault_args[0]);
  24.   stacked_r1 = ((unsigned long) hardfault_args[1]);
  25.   stacked_r2 = ((unsigned long) hardfault_args[2]);
  26.   stacked_r3 = ((unsigned long) hardfault_args[3]);
  27.   stacked_r12 = ((unsigned long) hardfault_args[4]);
  28.   stacked_lr = ((unsigned long) hardfault_args[5]);
  29.   stacked_pc = ((unsigned long) hardfault_args[6]);
  30.   stacked_psr = ((unsigned long) hardfault_args[7]);

  31.   UARTprintf ("[Hard fault handler]????n");
  32.   UARTprintf ("R0 = %x, R1 = %x, R2 = %x, R3 = %x, R12 = %xn", stacked_r0, stacked_r1, stacked_r2, stacked_r3);
  33.   UARTprintf ("R12 = %x, LR = %x, PC = %x, PSR = %xn", stacked_r12, stacked_lr, stacked_pc, stacked_psr);
  34.   UARTprintf ("BFAR = %xn", (*((volatile unsigned long *)(0xE000ED38))));
  35.   UARTprintf ("CFSR = %xn", (*((volatile unsigned long *)(0xE000ED28))));
  36.   UARTprintf ("HFSR = %xn", (*((volatile unsigned long *)(0xE000ED2C))));
  37.   UARTprintf ("DFSR = %xn", (*((volatile unsigned long *)(0xE000ED30))));
  38.   UARTprintf ("AFSR = %xn", (*((volatile unsigned long *)(0xE000ED3C))));

  39. #if 0
  40.     Debug ("Now Task : %snr",OSTCBPrioTbl[OSTCBCur->OSTCBPrio]->OSTCBTaskName);
  41.     OS_TaskStkCheck(TRUE);
  42.     OS_DebugHeap();
  43.     Q_ErrorStopScreen("HardFaultException");
  44. #endif

  45.   while(1) { }
  46. }

  47. void GetSerialNO(void)
  48. {
  49.     u32 Dev_Serial0, Dev_Serial1, Dev_Serial2;

  50.     Dev_Serial0 = HWREG(0x1FFFF7E8);
  51.   Dev_Serial1 = HWREG(0x1FFFF7EC);
  52.   Dev_Serial2 = *(vu32*)(0x1FFFF7F0);

  53.   DEBUG_PRINT("SerialNO = %08X %08X %08Xn", Dev_Serial0, Dev_Serial1, Dev_Serial2);
  54.   //SerialNO = 066C0036 33315330 43184129
  55. }

  56. //本函数名不可改, uCOS中应用到
  57. u32 GetClocksFreq(void)
  58. {
  59.     RCC_ClocksTypeDef rcc_clocks;

  60.   RCC_GetClocksFreq(&rcc_clocks);    //获取系统频率
  61.   return(rcc_clocks.HCLK_Frequency);
  62. }

  63. //--- 独立看门狗
  64. void IWDG_Init(unsigned char ucSecond)
  65. {
  66.     IWDG->KR = 0X5555;                //使能对IWDG->PR和IWDG->RLR的写
  67.   IWDG->PR = IWDG_Prescaler_64; //设置分频系数
  68.   IWDG->RLR = 625*ucSecond;         //从加载寄存器 IWDG->RLR
  69.     IWDG->KR = 0XAAAA;                //reload
  70.   IWDG->KR = 0XCCCC;                //使能看门狗
  71. }

  72. //THUMB指令不支持汇编内联, 采用如下方法实现执行汇编指令WFI
  73. __asm void WFI_SET(void)
  74. {
  75.     WFI;
  76. }

  77. //进入待机模式
  78. void SystemStandby(void)
  79. {
  80.     SCB->SCR      |= 1<<2;        //使能SLEEPDEEP位 (SYS->CTRL)
  81.   RCC->APB1ENR |= 1<<28;     //使能电源时钟
  82.     RCC->APB1ENR |= 1<<27;     //使能备份时钟
  83.     PWR->CSR      |= 1<<8; //设置WKUP用于唤醒
  84.     PWR->CR      |= 1<<2; //清除Wake-up 标志
  85.     PWR->CR      |= 1<<1; //PDDS置位
  86.     WFI_SET();                     //执行WFI指令
  87. }

  88. //--------------------- UART Begin -----------------------------------------------------
  89. extern COM_TypeDef g_DebugComNo;

  90. #define EVAL_COM1 USART1
  91. #define EVAL_COM1_GPIO GPIOA
  92. #define EVAL_COM1_CLK RCC_APB2Periph_USART1
  93. #define EVAL_COM1_GPIO_CLK RCC_APB2Periph_GPIOA
  94. #define EVAL_COM1_RxPin GPIO_Pin_10
  95. #define EVAL_COM1_TxPin GPIO_Pin_9

  96. #define EVAL_COM2 USART2
  97. #define EVAL_COM2_GPIO GPIOA
  98. #define EVAL_COM2_CLK RCC_APB1Periph_USART2
  99. #define EVAL_COM2_GPIO_CLK RCC_APB2Periph_GPIOA
  100. #define EVAL_COM2_RxPin GPIO_Pin_3
  101. #define EVAL_COM2_TxPin GPIO_Pin_2

  102. #define COMn 2
  103. USART_TypeDef* COM_USART[COMn] = {EVAL_COM1, EVAL_COM2};
  104. GPIO_TypeDef* COM_PORT[COMn] = {EVAL_COM1_GPIO, EVAL_COM2_GPIO};
  105. const uint32_t COM_USART_CLK[COMn] = {EVAL_COM1_CLK, EVAL_COM2_CLK};
  106. const uint32_t COM_POR_CLK[COMn] = {EVAL_COM1_GPIO_CLK, EVAL_COM2_GPIO_CLK};
  107. const uint16_t COM_TX_PIN[COMn] = {EVAL_COM1_TxPin, EVAL_COM2_TxPin};
  108. const uint16_t COM_RX_PIN[COMn] = {EVAL_COM1_RxPin, EVAL_COM2_RxPin};

  109. /*typedef enum {
  110.     GPIO_Mode_AIN = 0x0,         //模拟输入
  111.     GPIO_Mode_IN_FLOATING = 0x04,     //浮空输入模式, 默认
  112.     GPIO_Mode_IPD = 0x28,     //上拉/下拉输入模式
  113.     GPIO_Mode_IPU = 0x48,             //保留
  114.     GPIO_Mode_Out_OD = 0x14,         //通用开漏输出
  115.     GPIO_Mode_Out_PP = 0x10,         //通用推挽输出,     无输出.
  116.     GPIO_Mode_AF_OD = 0x1C,                 //复用(开漏)输出
  117.     GPIO_Mode_AF_PP = 0x18                 //复用(推挽)输出. 乱码
  118. } GPIOMode_TypeDef; */
  119. void USART_Set(COM_TypeDef COM, uint32 BaudRate)
  120. {
  121.     USART_InitTypeDef USART_InitStructure;
  122.     GPIO_InitTypeDef GPIO_InitStructure;

  123.     USART_InitStructure.USART_BaudRate = BaudRate;
  124.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  125.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
  126.     USART_InitStructure.USART_Parity = USART_Parity_No;
  127.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  128.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  129.     /* Enable GPIO clock */
  130.     RCC_APB2PeriphClockCmd(COM_POR_CLK[COM] | RCC_APB2Periph_AFIO, ENABLE);    //使能串口所有GPIO模块时钟,并使能AFIO模块时钟

  131.     /* Enable UART clock */
  132.     if (COM == COM1) {
  133.         RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE);     //使能串口模块时钟
  134.     }
  135.     else {
  136.         RCC_APB1PeriphClockCmd(COM_USART_CLK[COM], ENABLE);        //使能串口模块时钟
  137.     }

  138.     /* Configure USART Tx as alternate function push-pull */
  139.     GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[COM];        //设置TX引脚
  140.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  141.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  142.     GPIO_Init(COM_PORT[COM], &GPIO_InitStructure);

  143.     /* Configure USART Rx as input floating */
  144.     GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM];            //设置RX引脚
  145.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //浮空输入
  146.     GPIO_Init(COM_PORT[COM], &GPIO_InitStructure);

  147.     /* USART configuration */
  148.     USART_Init(COM_USART[COM], &USART_InitStructure);        //初始化USART

  149.     /* Enable USART Receive and Transmit interrupts */
  150.     USART_ITConfig(COM_USART[COM], USART_IT_RXNE, ENABLE);
  151.     //USART_ITConfig(COM_USART[COM], USART_IT_TXE, ENABLE);

  152.     /* Enable USART */
  153.     USART_Cmd(COM_USART[COM], ENABLE);        //使能串口模块
  154.     //USART_DMACmd(COM, USART_DMAReq_Rx, ENABLE); //使能UART DAM传输
  155. }

  156. void UARTSendChar(COM_TypeDef COM, uint8_t ch)
  157. {
  158.     /* Loop until the end of transmission */
  159.     //USART_SendData(COM_USART[COM], ch);
  160.     while (USART_GetFlagStatus(COM_USART[COM], USART_FLAG_TC) == RESET);
  161.     USART_SendData(COM_USART[COM], ch);
  162. }

  163. void UARTOut(COM_TypeDef COM, uint8_t *Data, uint16_t Len)
  164. {
  165.     uint16_t i;

  166.     for(i=0; i<Len; i++) {
  167.         UARTSendChar(COM, Data[i]);
  168.     }
  169. }

  170. //--- used by UARTprintf
  171. void UARTwrite(const char *pucBuffer, unsigned long ulCount)
  172. {
  173.     // Loop while there are more characters to send, Write the next character to the UART.
  174.     while(ulCount--) {
  175.         if(*pucBuffer == 'n') {
  176.             UARTSendChar(g_DebugComNo, 'r');
  177.         }
  178.         UARTSendChar(g_DebugComNo, *pucBuffer++);
  179.     }
  180. }

  181. #if 0
  182. #define UARTSOF '$'
  183. #define UARTEOF 0x0d
  184. unsigned char RxBuffer1[100];
  185. unsigned short RxCounter1;

  186. void USART1_IRQHandler(void)
  187. {
  188.   unsigned char ucTmp;
  189. #ifdef RTX_KERNEL
  190.   void *msg;
  191. #endif
  192. #ifdef UCOS_KERNEL
  193.     INPUT_EVENT IE;

  194.     OS_IntEnter();
  195. #endif

  196.   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  197.   {
  198.     /* Read one byte from the receive data register */
  199.     ucTmp = USART_ReceiveData(USART1);

  200.     if (ucTmp == UARTSOF) {
  201.         RxCounter1 = 1;
  202.         RxBuffer1[0] = ucTmp;
  203.     }
  204.     else if(ucTmp == UARTEOF) {
  205.       /* Disable the USART1 Receive interrupt */
  206.       //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
  207.       RxBuffer1[RxCounter1] = '';        //结束符.

  208. #ifdef RTX_KERNEL
  209.         msg = malloc(RxCounter1);
  210.         strcpyx((U8 *)msg, RxBuffer1);
  211.         isr_mbx_send(COMReceiveMailbox, msg);
  212. #else
  213. #ifdef UCOS_KERNEL
  214.         //串口输入事件
  215.         IE.uType     = Sync_Type;
  216.         IE.EventType= Input_UartInput;
  217.         IE.Num        = 1;//表示串口1
  218.         //IE.Info.SyncInfo.IntParam    = ((IE.Num<<16) + RxCounter1);
  219.         IE.Info.SyncInfo.IntParam    = RxCounter1;
  220.         IE.Info.SyncInfo.pParam        = RxBuffer1;
  221.         OS_MsgBoxSend(gInputHandler_Queue, &IE, 100);

  222. #else
  223.          UARTprintf("%sn", RxBuffer1);
  224. #endif
  225. #endif

  226.         RxCounter1 = 0;
  227.     }
  228.     else if (IS_AF(ucTmp) || IS_af(ucTmp) || IS_09(ucTmp)) {
  229.         RxBuffer1[RxCounter1++] = ucTmp;
  230.     }
  231.   }
  232.   USART_ClearITPendingBit(USART1, USART_IT_RXNE);//清除中断标志

  233. #ifdef UCOS_KERNEL
  234.     OS_IntExit();
  235. #endif
  236. }
  237. #endif

  238. //----------------------------- 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");
}




阅读(3161) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~