系统类封装完成,编译通过

This commit is contained in:
nnhy 2014-07-24 19:17:22 +00:00
parent 269c9aa2b3
commit 42d4f45e84
6 changed files with 358 additions and 33 deletions

View File

@ -20,7 +20,7 @@ typedef struct TIntState
} IntState; } IntState;
/*默认按键去抖延时 70ms*/ /*默认按键去抖延时 70ms*/
//static byte shake_time=70; static byte shake_time=70;
// 16条中断线 // 16条中断线
static IntState State[16]; static IntState State[16];
@ -200,7 +200,7 @@ void GPIO_ISR (int num) // 0 <= num <= 15
//value = TIO_Read(state->Pin); // 获取引脚状态 //value = TIO_Read(state->Pin); // 获取引脚状态
EXTI->PR = bit; // 重置挂起位 EXTI->PR = bit; // 重置挂起位
value = Port::Read(state->Pin); // 获取引脚状态 value = Port::Read(state->Pin); // 获取引脚状态
// Sys.Sleep(shake_time); // 避免抖动 在os_cfg.h里面修改 Sys.Sleep(shake_time); // 避免抖动 在os_cfg.h里面修改
} while (EXTI->PR & bit); // 如果再次挂起则重复 } while (EXTI->PR & bit); // 如果再次挂起则重复
//EXTI_ClearITPendingBit(line); //EXTI_ClearITPendingBit(line);
if(state->Handler) if(state->Handler)
@ -271,21 +271,7 @@ void EXTI4_15_IRQHandler(void)
#endif //IT #endif //IT
void Tio_SetShakeTime(byte time_ms) void Port::SetShakeTime(byte ms)
{ {
// shake_time=time_ms; shake_time = ms;
} }
// .............................IO端口函数初始化.............................
/*void TIO_Init(TIO* this)
{
int i = 0;
this->Open = TIO_Open;
this->OpenPort = TIO_OpenPort;
this->Close = TIO_Close;
this->Write = TIO_Write;
this->Read = TIO_Read;
this->Register = TIO_Register;
this->SetShakeTime=Tio_SetShakeTime;
for(i=0; i<16; i++) TIO_Register(i, 0);
}*/

1
Port.h
View File

@ -41,6 +41,7 @@ public:
static void Write(Pin pin, bool value); static void Write(Pin pin, bool value);
static bool Read(Pin pin); static bool Read(Pin pin);
static void Register(Pin pin, IOReadHandler handler); static void Register(Pin pin, IOReadHandler handler);
static void SetShakeTime(byte ms);
}; };
#endif //_Port_H_ #endif //_Port_H_

View File

@ -49,7 +49,7 @@ void SerialPort::Open()
// 检查重映射 // 检查重映射
#ifdef STM32F1XX #ifdef STM32F1XX
if(IS_REMAP(_com)) if(IsRemap)
{ {
switch (_com) { switch (_com) {
case 0: AFIO->MAPR |= AFIO_MAPR_USART1_REMAP; break; case 0: AFIO->MAPR |= AFIO_MAPR_USART1_REMAP; break;
@ -151,10 +151,12 @@ void SerialPort::Close()
//Sys.IO.Close(tx); //Sys.IO.Close(tx);
//Sys.IO.Close(rx); //Sys.IO.Close(rx);
Port::SetAlternate(tx);
Port::SetAlternate(rx);
// 检查重映射 // 检查重映射
#ifdef STM32F1XX #ifdef STM32F1XX
if(IS_REMAP(_com)) if(IsRemap)
{ {
switch (_com) { switch (_com) {
case 0: AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP; break; case 0: AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP; break;
@ -264,8 +266,7 @@ extern "C"
/* 重载fputc可以让用户程序使用printf函数 */ /* 重载fputc可以让用户程序使用printf函数 */
int fputc(int ch, FILE *f) int fputc(int ch, FILE *f)
{ {
//int _com = Sys.MessagePort; int _com = Sys.MessagePort;
int _com = 0;
if(_com == COM_NONE) return ch; if(_com == COM_NONE) return ch;
USART_TypeDef* port = g_Uart_Ports[_com]; USART_TypeDef* port = g_Uart_Ports[_com];

View File

@ -3,6 +3,14 @@
#include "Sys.h" #include "Sys.h"
/* 串口定义 */
#define COM1 0
#define COM2 1
#define COM3 2
#define COM4 3
#define COM5 4
#define COM_NONE 0xFF
// 读取委托 // 读取委托
typedef void (*SerialPortReadHandler)(byte data); typedef void (*SerialPortReadHandler)(byte data);

314
Sys.cpp Normal file
View File

@ -0,0 +1,314 @@
#include "Sys.h"
TSys Sys;
#ifndef BIT
#define BIT(x) (1 << (x))
#endif
#define RCC_CFGR_USBPRE_Div1 ((uint32_t)0x00400000) /*!< USB Device prescaler */
#define RCC_CFGR_USBPRE_1Div5 ((uint32_t)0x00000000) /*!< USB Device prescaler */
#define RCC_CFGR_USBPRE_Div2 ((uint32_t)0x00C00000) /*!< USB Device prescaler */
#define RCC_CFGR_USBPRE_2Div5 ((uint32_t)0x00800000) /*!< USB Device prescaler */
#define GD32_PLL_MASK 0x20000000
byte fac_us;//全局变量
volatile uint TickStat;//全局变量 为延时函数服务
/****************************************************
SYSCLK :
*****************************************************/
void delay_init(uint clk)
{
NVIC_InitTypeDef NVIC_InitStructure;
/****************************************
*SystemFrequency/1000 1ms中断一次 *
*SystemFrequency/100000 10us中断一次 *
*SystemFrequency/1000000 1us中断一次 *
*****************************************/
SysTick->CTRL &=~BIT(2);//选择外部时钟
SysTick->CTRL |=BIT(1);//开启定时器减到0后的中断请求
fac_us = clk/8;//计算好SysTick加载值
/*初始化部分代码*/
SysTick->LOAD = (uint)fac_us*1000-1;//加载时间值
SysTick->VAL = 1;//随便写个值,清除加载寄存器的值
SysTick->CTRL |= BIT(0);//SysTick使能
/* Configure the NVIC Preemption Priority Bits */
NVIC_InitStructure.NVIC_IRQChannel = (byte)SysTick_IRQn;
#ifdef STM32F10X
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
#else
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00; //想在中断里使用延时函数就必须让此中断优先级最高
#endif
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
__asm void TSys::DisableInterrupts()
{
/*
register UINT32 Primask __asm("primask");
UINT32 m = Primask;
__disable_irq();
return m ^ 1;
*/
#ifdef STM32F10X //stm32f030的汇编与此有所区别
MRS r0,PRIMASK
CPSID i
EOR r0,r0,#1
BX lr
#else
BX lr
#endif
}
__asm void TSys::EnableInterrupts()
{
/*
register UINT32 Primask __asm("primask");
UINT32 m = Primask;
__enable_irq();
return m ^ 1;
*/
// 这里打开中断以后,经常发生各种各样的异常,没有关系,并不是这里的错,而是之前可能就已经发生了异常,只不过无法产生中断,等到这里而已
#ifdef STM32F10X //stm32f030的汇编与此有所区别
MRS r0,PRIMASK
CPSIE i
EOR r0,r0,#1
BX lr
#else
BX lr
#endif
}
//利用SysTick定时器产生1ms时基
// SysTick_Handler 滴答定时器中断
void SysTick_Handler(void) //需要最高优先级 必须有抢断任何其他中断的能力才能 //供其他中断内延时使用
{
if(TickStat)
TickStat--;
}
/****************************************************
ms级延时
nms :
Delay_Init()
*****************************************************/
void TSys::Sleep(uint ms)
{
TickStat = ms;
while(TickStat);
}
/****************************************************
us级延时
nus :
Delay_Init()
*****************************************************/
void TSys::Delay(uint us)
{
uint t = SysTick->CTRL&0x00ffffff; //SysTick 为24位倒计数定时器
uint tc = fac_us * us;
//if(nus<100){for();retrun} //低于100微秒的延时就没有必要使用定时器作为时基了
if(us > 1000) //如果延迟超过1ms
{
Sleep(us / 1000);
// if(tc%1000==0)return; //几率比较小 忽略此句、
tc=(tc%1000)*fac_us;
}
if((t-tc)>0)
{
while(SysTick->CTRL>(t-tc));
return;
}
else if((t-tc)==0)
{
while(SysTick->CTRL);
return;
}
else
{
tc= SysTick->LOAD -(tc-t); //低于1s 所以
while(SysTick->CTRL!=tc);
return;
}
}
#if GD32F1
// 获取JTAG编号ST是0x041GD是0x7A3
uint16_t Get_JTAG_ID()
{
if( *( uint8_t *)( 0xE00FFFE8 ) & 0x08 )
{
return ((*(uint8_t *)(0xE00FFFD0) & 0x0F ) << 8 ) |
((*(uint8_t *)(0xE00FFFE4) & 0xFF ) >> 3 ) |
((*(uint8_t *)(0xE00FFFE8) & 0x07 ) << 5 ) + 1 ;
}
return 0;
}
void STM32_BootstrapCode()
{
uint n = 0;
uint RCC_CFGR_ADC_BITS = RCC_CFGR_ADCPRE_DIV8;
uint FLASH_ACR_LATENCY_BITS = 0;
uint RCC_CFGR_USBPRE_BIT = 0;
uint mull, mull2;
// 是否GD
bool isGD = Get_JTAG_ID() == 0x7A3;
if(isGD && Sys.Clock == 72000000) Sys.Clock = 120000000;
// 确保关闭中断为了方便调试Debug时不关闭
#ifndef DEBUG
//__disable_irq();
#endif
n = Sys.Clock / 14000000;
if (n < 6)
RCC_CFGR_ADC_BITS = RCC_CFGR_ADCPRE_DIV6;
else
RCC_CFGR_ADC_BITS = RCC_CFGR_ADCPRE_DIV8;
// GD32的Flash零等待
if (isGD)
FLASH_ACR_LATENCY_BITS = FLASH_ACR_LATENCY_0; // 不允许等待
else
FLASH_ACR_LATENCY_BITS = FLASH_ACR_LATENCY_2; // 等待两个
// 配置JTAG调试支持
DBGMCU->CR = DBGMCU_CR_DBG_TIM2_STOP | DBGMCU_CR_DBG_SLEEP;
// 允许访问未对齐内存不强制8字节栈对齐
SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP | SCB_CCR_STKALIGN);
// 捕获所有异常
CoreDebug->DEMCR |= CoreDebug_DEMCR_VC_HARDERR_Msk | CoreDebug_DEMCR_VC_INTERR_Msk |
CoreDebug_DEMCR_VC_BUSERR_Msk | CoreDebug_DEMCR_VC_STATERR_Msk |
CoreDebug_DEMCR_VC_CHKERR_Msk | CoreDebug_DEMCR_VC_NOCPERR_Msk |
CoreDebug_DEMCR_VC_MMERR_Msk;
// 为了配置时钟CPU必须运行在8MHz晶振上
RCC->CR |= RCC_CR_HSION;
while(!(RCC->CR & RCC_CR_HSIRDY));
// 切换到内部时钟
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
// RCC_CFGR_SW_HSI是0一点意义都没有
RCC->CFGR |= RCC_CFGR_SW_HSI; // sysclk = AHB = APB1 = APB2 = HSI (8MHz)
// 关闭 HSE 时钟
RCC->CR &= ~RCC_CR_HSEON;
// 关闭 HSE & PLL
RCC->CR &= ~RCC_CR_PLLON;
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
while(!(RCC->CR & RCC_CR_HSERDY));
// 设置Flash访问时间并打开预读缓冲
FLASH->ACR = FLASH_ACR_LATENCY_BITS | FLASH_ACR_PRFTBE;
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
// 支持超频主频必须是8M的倍频
mull = Sys.Clock / Sys.CystalClock;
mull2 = (mull - 2) << 18;
// 处理0.5倍频
if( (mull * Sys.CystalClock + Sys.CystalClock / 2) == Sys.Clock )
{
mull = 2 * Sys.Clock / Sys.CystalClock;
// 对于GD32的108MHz没有除尽。
if( isGD && mull > 17 )
mull2 = (mull - 17) << 18 | RCC_CFGR_PLLXTPRE_HSE_Div2 | GD32_PLL_MASK;
else
mull2 = (mull - 2 ) << 18 | RCC_CFGR_PLLXTPRE_HSE_Div2;
}
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | mull2);
switch ( 2 * Sys.Clock / 48000000 )
{
case 2:
RCC_CFGR_USBPRE_BIT = RCC_CFGR_USBPRE_Div1;
break;
case 3:
RCC_CFGR_USBPRE_BIT = RCC_CFGR_USBPRE_1Div5;
break;
case 4:
RCC_CFGR_USBPRE_BIT = RCC_CFGR_USBPRE_Div2;
break;
case 5:
RCC_CFGR_USBPRE_BIT = RCC_CFGR_USBPRE_2Div5;
break;
default:
RCC_CFGR_USBPRE_BIT = RCC_CFGR_USBPRE_Div1;
break;
}
// 最终时钟配置
RCC->CFGR |= RCC_CFGR_USBPRE_BIT // USB clock
| RCC_CFGR_HPRE_DIV1 // AHB clock
| RCC_CFGR_PPRE1_DIV2 // APB1 clock
| RCC_CFGR_PPRE2_DIV1 // APB2 clock
| RCC_CFGR_ADC_BITS; // ADC clock (max 14MHz)
// 打开 HSE & PLL
RCC->CR |= RCC_CR_PLLON;// | RCC_CR_HSEON;
// 等到 PPL 达到时钟频率
while(!(RCC->CR & RCC_CR_PLLRDY));
// 最终时钟配置
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL; // sysclk = pll out (SYSTEM_CLOCK_HZ)
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08);
// 最小化外设时钟
RCC->AHBENR = RCC_AHBENR_SRAMEN | RCC_AHBENR_FLITFEN;
RCC->APB2ENR = RCC_APB2ENR_AFIOEN;
RCC->APB1ENR = RCC_APB1ENR_PWREN;
// 关闭 HSI 时钟
RCC->CR &= ~RCC_CR_HSION;
// 计算当前工作频率
mull = RCC->CFGR & ((int)0x3C0000 | GD32_PLL_MASK);
if((mull & GD32_PLL_MASK) != 0) // 兼容GD32的108MHz
mull = (((mull)&(0x003C0000)) >> 18) + 17;
else
mull = ( mull >> 18) + 2;
//TSys::Frequency = HSI_VALUE * pllmull;
// 不能直接用HSI_VALUE因为不同的硬件设备使用不同的晶振
Sys.Clock = Sys.CystalClock * mull;
if( (RCC->CFGR & RCC_CFGR_PLLXTPRE_HSE_Div2) && !isGD ) Sys.Clock /= 2;
}
#endif
void TSys::Init(void)
{
#ifndef GD32F1
RCC_ClocksTypeDef clock;
RCC_GetClocksFreq(&clock);
Clock = clock.SYSCLK_Frequency;
#endif
#ifdef STM32F10X
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4); //中断优先级分配方案4 四位都是抢占优先级
#endif
ID[0] = *(__IO uint *)(0X1FFFF7F0); // 高字节
ID[1] = *(__IO uint *)(0X1FFFF7EC); //
ID[2] = *(__IO uint *)(0X1FFFF7E8); // 低字节
FlashSize = *(__IO ushort *)(0X1FFFF7E0); // 容量
#if GD32F1
STM32_BootstrapCode();
#endif
delay_init(Clock/1000000);
}

37
Sys.h
View File

@ -1,5 +1,5 @@
#ifndef _SYSTEM_H_ #ifndef _Sys_H_
#define _SYSTEM_H_ #define _Sys_H_
#include <stdio.h> #include <stdio.h>
#include "stm32.h" #include "stm32.h"
@ -14,14 +14,6 @@ typedef char* string;
#define true 1 #define true 1
#define false 0 #define false 0
/* ´®¿Ú¶¨Òå */
#define COM1 0
#define COM2 1
#define COM3 2
#define COM4 3
#define COM5 4
#define COM_NONE 0xFF
/*Spi定义*/ /*Spi定义*/
//SPI1..这种格式与st库冲突 //SPI1..这种格式与st库冲突
#define SPI_1 0 #define SPI_1 0
@ -33,4 +25,27 @@ typedef char* string;
typedef ushort Pin; typedef ushort Pin;
#include "Pin.h" #include "Pin.h"
#endif //_SYSTEM_H_ // 系统类
class TSys
{
public:
bool Debug; // 是否调试
uint Clock; // 系统时钟
#if GD32F1
uint CystalClock; // 晶振时钟
#endif
byte MessagePort; // 消息口默认0表示USART1
uint ID[3]; // 芯片ID
uint FlashSize; // 芯片Flash容量
void Init(); // 初始化系统
void Sleep(uint ms); // 毫秒级延迟
void Delay(uint us); // 微秒级延迟
void DisableInterrupts(); // 关闭中断
void EnableInterrupts(); // 打开中断
};
extern TSys Sys;
#endif //_Sys_H_