SRR算法c语言实现线性优先级,时间触发+protothread思想+支持优先级的非抢占类OS调度器...

/* Includes ------------------------------------------------------------------*/

#include "user.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

static void TIM1_PWM_Config(void);

static void TIM4_Config(void);

static void GPIO_Config(void);

static void UART1_Config(void);

static void ADC_Config(void);

static void IWDG_Config(void);

static void WWDG_Config(void);

static void IT_Config(void);

/* Public functions ----------------------------------------------------------*/

void CLK_Config(void)

{

//配置内部16M时钟作为时钟源

//CLK_ICKR_HSIEN = 1;       //使能内部高速时钟(复位值)

CLK_ICKR_bit.LSIEN    = 1;  //使能内部低速时钟

CLK_CKDIVR_bit.HSIDIV = 0;  //主时钟分频 0-3对应 1 2 4 8分频

CLK_CKDIVR_bit.CPUDIV = 0;  //CPU时钟分频 0-7对应 1 2 4 8 16 32 64 128分频

//CLK_SWR = 0xE1;                 //HSI为主时钟源(复位值)

//CLK_SWCR_SWEN  = 1;             //使能自动切换时钟

//CLK_SWR = 0xD2;                 //0xD2:LSI为主时钟源(仅当LSI_EN选项位为1时)

//CLK_SWR = 0xB4;                 //0xB4:HSE为主时钟源

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

asm("nop");

//外设时钟控制寄存器 CLK_PCKENR1

//        CLK_PCKENR1 = 0x00;        //复位值为0xff,即默认为开启状态

//        PCKEN10: I2C

//        PCKEN11: SPI

//        PCKEN12: UART1

//        PCKEN13: UART2/3   实测此位才是UART1时钟使能(stm8s103f3)

//        PCKEN14: TIM4

//        PCKEN15: TIM2

//        PCKEN16: TIM3

//        PCKEN17: TIM1

CLK_PCKENR1 = b10011000;    //使能TIM1,TIM4,UART1 时钟

//外设时钟控制寄存器 CLK_PCKENR2

//        CLK_PCKENR2 = 0x00;        //复位值为0xff,即默认为开启状态

//        PCKEN20: Reserved

//        PCKEN21: Reserved

//        PCKEN22: AWU

//        PCKEN23: ADC

//        PCKEN24: Reserved

//        PCKEN25: Reserved

//        PCKEN26: Reserved

//        PCKEN27: CAN

CLK_PCKENR2 = b00001000;  //使能 ADC 时钟,

//LK_CSSR_CSSEN = 1;                  //使能时钟监控功能,外间时钟出问题时切换到内部时钟源HSI/8   CLK_CSSR中的CSSD位被置位

//LK_CCOR = ;                                //时钟输出寄存器

}

void Peripherals_Config(void)

{

GPIO_Config();

TIM1_PWM_Config();

TIM4_Config();

UART1_Config();

ADC_Config();

IWDG_Config();

WWDG_Config();

IT_Config();  //中断相关配置

}

static void IWDG_Config(void)

{

IWDG_KR  = 0x55;        //关写保护

IWDG_PR  = 0x00;        //预分频系数4   0-6对应  4 8 16 32 64 128 256 分频

IWDG_RLR = 0xFF;        //最长超时15.90 ms

IWDG_KR  = 0xAA;        //恢复写保护,同时相关于清狗指令->用IWDG_RLR的数值刷新计数器的内容,避免了产生看门狗的复位

//其实以上看门狗配置均为上电复位值

IWDG_KR  = 0xCC;        //启动独立看门狗

IWDG_KR  = 0xAA;        //清狗

}

static void WWDG_Config(void)

{

WWDG_WR = 0x7f;

WWDG_CR = (uint8_t)(0x80 | WWDG_COUNTER_INIT);

WWDG_WR = (uint8_t)((uint8_t)(~0x80) & (uint8_t)(0x40 | WWDG_WINDOW_VALUE));

}

static void GPIO_Config(void)

{

PA_ODR = b00000000;           //初始化输出低电平

PA_DDR = b11111111;           // 1=output

PA_CR1 = b11111111;           //1=上拉输入或推挽输出  0=浮空输入或开漏输出    ADC时应选浮空输入,无中断

PA_CR2 = b00000000;           //1=使能外部中断或10M输出  0=禁止外部中断或2M输出  中断边沿在EXTI_CRX中设置

PB_ODR = b00000000;           //初始化输出低电平

PB_DDR = b11111111;           // 1=output                             PB4 INPUT

PB_CR1 = b11111111;           //1=上拉输入或推挽输出  0=浮空输入或开漏输出    ADC时应选浮空输入,无中断

PB_CR2 = b00000000;           //1=使能外部中断或10M输出  0=禁止外部中断或2M输出  中断边沿在EXTI_CRX中设置

PC_ODR = b00000000;           //初始化输出电平

PC_DDR = b11111111;           // 1=output           PC4 INPUT

PC_CR1 = b11111111;           //1=上拉输入或推挽输出  0=浮空输入或开漏输出    ADC时应选浮空输入,无中断

PC_CR2 = b00000000;           //1=使能外部中断或10M输出  0=禁止外部中断或2M输出  中断边沿在EXTI_CRX中设置

//        如果硬件上没有连接RST脚,则SWIM引脚(PD1)不能配置为输出口,否则不能连上ST-LINK

PD_ODR = b00100000;           //初始化输出低电平  PD5=TX初始化输出高电平,PD6=RX配置为输入

PD_DDR = b10100011;           // 1=output 0=input PD2=AIN3 PD3=AIN4

PD_CR1 = b11111111;           //1=上拉输入或推挽输出  0=浮空输入或开漏输出    ADC时应选浮空输入,无中断

PD_CR2 = b00010000;           //1=使能外部中断或10M输出  0=禁止外部中断或2M输出  中断边沿在EXTI_CRX中设置

//PD4作为下降沿中断测试输入引脚,配置为上拉输入

PE_ODR = b00000000;           //初始化输出低电平

PE_DDR = b11111111;           // 1=output

PE_CR1 = b11111111;           //1=上拉输入或推挽输出  0=浮空输入或开漏输出    ADC时应选浮空输入,无中断

PE_CR2 = b00000000;           //1=使能外部中断或10M输出  0=禁止外部中断或2M输出  中断边沿在EXTI_CRX中设置

}

static void TIM1_PWM_Config(void)

{

//须要在选项字节中配置使能对应的PWM功能管脚,同时开启对应的时钟

TIM1_PSCRH = 0x00;   //预分频器   16bit  fCK_CNT = fCK_PSC / (PSCR[15:0] + 1)

TIM1_PSCRL = 0x00;

TIM1_ARRH = (uint8_t)((800 - 1) >> 8); //自动重载值 16bit  即周期寄存器 16M/800=20K

TIM1_ARRL = (uint8_t)((800 - 1));

//TIM1_CR1

//TIM1_CR1_bit.CEN  = 1;  //CEN:允许计数,最后再开启

TIM1_CR1_bit.UDIS = 0;  //UDIS:禁止更新

TIM1_CR1_bit.URS  = 0;  //URS:更新请求源

TIM1_CR1_bit.OPM  = 0;  //0:在发生更新事件时,计数器不停止;

TIM1_CR1_bit.DIR  = 0;  //0:计数器向上计数;

TIM1_CR1_bit.CMS  = 0;  //00:边沿对齐模式。计数器依据方向位(DIR)向上或向下计数。

TIM1_CR1_bit.ARPE = 1;  //1:TIM1_ARR寄存器由预装载缓冲器缓冲。

TIM1_EGR_bit.UG   = 1;  //产生一次更新事件,更新分频系数与TIMx_CNTR

TIM1_RCR  = 0x00; //重复计数寄存器,即Reload事件发生了多少次:TIM1_RCR+1

//这意味着在PWM模式中,(TIM1_RCR+1)对应着:

//- 在边沿对齐模式下,PWM周期的数目;

//- 在中心对称模式下,PWM半周期的数目;

//  通道1;

TIM1_CCMR1_bit.CC1S  = 0;   //CC1S[1:0]:捕获/比较1 选择

TIM1_CCMR1_bit.OC1FE = 0;   //OC1FE:输出比较1 快速使能

TIM1_CCMR1_bit.OC1PE = 1;   //OC1PE:输出比较1预装载使能

TIM1_CCMR1_bit.OC1M  = 7;   //110:PWM模式1,111:模式2

TIM1_CCMR1_bit.OC1CE = 0;   //0:OC1REF 不受ETRF输入(来自TIM1_TRIG引脚)的影响;  1:一旦检测到ETRF输入高电平,OC1REF=0。

TIM1_CCER1_bit.CC1E  = 1;   //1=输出使能

TIM1_CCER1_bit.CC1P  = 0;   //0=高电平有效 P

TIM1_CCER1_bit.CC1NE = 1;   //1=输出使能        --

TIM1_CCER1_bit.CC1NP = 0;   //0=高电平有效--互补输出  N

TIM1_CCR1H = 0x00;

TIM1_CCR1L = 0x00;                                   //占空比寄存器,CH1

//  通道2;

TIM1_CCMR2_bit.CC2S  = 0;   //CC1S[1:0]:捕获/比较1 选择

TIM1_CCMR2_bit.OC2FE = 0;   //OC1FE:输出比较1 快速使能

TIM1_CCMR2_bit.OC2PE = 1;   //OC1PE:输出比较1预装载使能

TIM1_CCMR2_bit.OC2M  = 7;   //110:PWM模式1,111:模式2

TIM1_CCMR2_bit.OC2CE = 0;   //0:OC1REF 不受ETRF输入(来自TIM1_TRIG引脚)的影响;  1:一旦检测到ETRF输入高电平,OC1REF=0。

TIM1_CCER1_bit.CC2E  = 1;   //1=输出使能

TIM1_CCER1_bit.CC2P  = 0;   //0=高电平有效 P

TIM1_CCER1_bit.CC2NE = 1;   //1=输出使能        --                              //

TIM1_CCER1_bit.CC2NP = 0;   //0=高电平有效--互补输出  N

TIM1_CCR2H = 0x00;

TIM1_CCR2L = 0x00;                                   //占空比寄存器,CH2

//        TIM1_CR2 = ;

//        TIM1_SMCR = ;        从模式控制寄存器

//        TIM1_ETR = ;        外部触发寄存器

//TIM1_IER 中断使能寄存器

TIM1_IER_bit.UIE   = 1; //更新中断

TIM1_IER_bit.CC1IE = 0; //捕获/比较1中断

TIM1_IER_bit.CC2IE = 0; //捕获/比较2中断

TIM1_IER_bit.CC3IE = 0; //捕获/比较3中断

TIM1_IER_bit.CC4IE = 0; //捕获/比较4中断

TIM1_IER_bit.COMIE = 0; //COM中断

TIM1_IER_bit.TIE   = 0; //触发中断

TIM1_IER_bit.BIE   = 0; //刹车中断

//        TIM1_SR1 = ;        状态寄存器 1

//        TIM1_SR2 = ;        状态寄存器 2

//        TIM1_EGR = ;        事件产生寄存器

//刹车寄存器

TIM1_BKR_bit.MOE  = 1;  //1:如果设置了相应的使能位(TIM1_CCERX寄存器的CCIE位),则使能OC和OCN输出

TIM1_CR1_bit.CEN  = 1;  //CEN:允许计数

}

/**

* @brief  Configure TIM2 to generate an update interrupt each 0.5ms

* @param  None

* @retval None

*/

void TIM4_Config(void)

{

//IM4_PSCR_bit.PSC = 7; //分频值: 2^PSC[2:0]  定时器时钟源为内部时钟(fMASTER)。   (1/16M)*128=8us

//IM4_ARR      = 124;                //自动重载值    (124+1)*8us=1ms

TIM4_PSCR_bit.PSC = 4;  //分频值: 2^PSC[2:0]         1/16M)*2^4=1us

TIM4_ARR      = 99;     //自动重载值          (99+1)us

TIM4_EGR_bit.UG   = 1;  //产生一次更新事件,更新分频系数与TIM4_CNTR

TIM4_CR1_bit.ARPE = 1;  //1:TIM4_ARR寄存器通过缓冲预装载

TIM4_SR_bit.UIF   = 0;  //TIM4 溢出中断标志

TIM4_IER_bit.UIE  = 1;  //使能TIM4 溢出中断

TIM4_CR1_bit.CEN  = 1;  //使能TIM4

}

/**

* @brief  UART1 Configuration for interrupt communication

* @param  None

* @retval None

*/

//

static void UART1_Config(void)

{

WORD_UNION UART1_BRR;

UART1_CR1_bit.PIEN  = 0; //校验中断使能  0:中断被禁止   1:当USART_SR中的PE为1时,产生USART中断

UART1_CR1_bit.PS    = 0; //0:偶校验。 1:奇校验

UART1_CR1_bit.PCEN  = 0; //1:奇偶校验控制被使能

UART1_CR1_bit.WAKE  = 0; //唤醒方法

UART1_CR1_bit.M     = 0; //8bit数据格式

UART1_CR1_bit.UART0 = 0; //0:UART使能  1:UART预分频器和输出禁用

UART1_CR1_bit.T8    = 0; //9bit数据格式 下的发送数据位8

UART1_CR1_bit.R8    = 0; //9bit数据格式 下的接收数据位8

UART1_CR3_bit.STOP = 0; //00:1个停止位;01:保留 10:2个停止位;11:1.5个停止位;

UART1_BRR.all = 1666;   //16M/1666=9603

//UART1_BRR2=UART_DIV[15:12]高4位  UART_DIV[3:0]低4位

UART1_BRR2  = UART1_BRR.byte.H & 0xf0;

UART1_BRR2 |= UART1_BRR.byte.L & 0x0f;

//UART1_BRR1=UART_DIV[11:4]

UART1_BRR1 = (uint8_t)(UART1_BRR.all>>4); //中间8位

//UART1_CR2_bit.SBK  = 1;        //SBK: 发送断开帧

//UART1_CR2_bit.RWU  = 1;        //RWU: 接收唤醒

UART1_CR2_bit.REN  = 1; //接收使能

UART1_CR2_bit.TEN  = 1; //发送使能

//UART1_CR2_bit.ILIEN= 1;        //ILIEN: IDLE中断使能

UART1_CR2_bit.RIEN = 1; //接收中断使能  1:当USART_SR中的OR或者RXNE为1时,产生USART中断。

//UART1_CR2_bit.TCIEN= 1;        //发送完成中断使能 1:当USART_SR中的TC为1时,产生USART中断。要发送时再使能中断(会立即产生中断)

//UART1_CR2_bit.TIEN = 1;        //发送中断使能  1:当USART_SR中的TXE为1时,产生USART中断。

//UART1_SR_bit.TC &= 0;          //读该位来清零

//UART1_DR = 0xaa;                    //写入要发送的数据

}

/**

* @brief  Configure ADC

*

* @param  None

* @retval None

*/

static void ADC_Config(void)

{

//        当作为模拟输入时可以关闭输入施密特触发器来降低功耗

ADC_TDRH = b00000000;       //1=ADC输入禁止施密特触发 ***********ADC时应选浮空输入,无中断

ADC_TDRL = b00011000;       //共16通道   AIN3-AIN4

ADC_CR1_bit.ADON  = 0;      //ADON:  A/D 转换开/关

ADC_CR1_bit.CONT  = 0;      // 0:单次转换模式  1:连续转换模式

ADC_CR1_bit.SPSEL = 0;      // 预分频选择位 000->111对应 2 3 4 6 8 10 12 18分频

//ADC_CR2_bit.SCAN    = 1;          //1:使能扫描模式 0:不使能扫描模式

ADC_CR2_bit.ALIGN   = 1;    //1:数据右对齐。(低8字节在ADC_DRL寄存器,其余高字节位在ADC_DRH寄存器)读顺序

//应先读低位,再读高位字节或整个一起读

ADC_CR2_bit.EXTSEL  = 0;    //外部事件触发和启动ADC   00:内部定时器1  TRG事件  01:ADC_ETR  引脚上的外部中断 其它值保留

ADC_CR2_bit.EXTTRIG = 0;    //EXTTRIG:  外触发使能位

//ADC_CR3_bit.OVR  = 0;                    //1:数据缓存发生了数据溢出事件

ADC_CR3_bit.DBUF = 0;       //1:数据缓存功能使能,扫描模式时使用.

ADC_CSR_bit.CH    = 4;      // CH[3:0] : 选择转换通道    或指定从AN0到ANx扫描转换

//ADC_CSR_bit.AWDIE = 0;                  //1: 使能AWD模拟看门狗中断

//ADC_CSR_bit.EOCIE = 1;                  //1:使能转换结束中断

//ADC_CSR_bit.AWD   = 0;                  //AWD:  模拟看门狗标志

ADC_CSR_bit.EOC   = 0;      //EOC:  转换结束

ADC_CR1_bit.ADON = 1;        //第一次置1将把ADC从低功耗模式下唤醒,之后才是启动ADC

//ADC_DBxRH        缓冲寄存器

//ADC_DBxRL

//ADC_DRL         数据寄存器

//ADC_DRH

}

void IT_Config(void)

{

//  中断配置------------------------------------------

//ITC_SPR3_bit.VECT11SPR = 0;//Timer1最低优先级,

//ITC_SPR4_bit.VECT15SPR = 0;//Timer3最低优先级,

//ITC_SPR6_bit.VECT21SPR = 0;        //UART1/3接收满 最低优先级

//ITC_SPR6_bit.VECT22SPR = 2; //adc中断为最高优先级

//ITC_SPR6_bit.VECT23SPR = 0;        //Timer4最低优先级,2为最高,3为禁止优先级(复位默认值)

//EXTI_CR1:外部中断控制寄存器1  设置何种边沿触发

EXTI_CR1_bit.PAIS = 0;//[1:0] 00:下降沿和低电平触发

EXTI_CR1_bit.PBIS = 0;//[3:2] 01:仅上升沿触发

EXTI_CR1_bit.PCIS = 0;//[5:4] 10:仅下降沿触发

EXTI_CR1_bit.PDIS = 2;//[7:6] 11:上升沿和下降沿触发

//EXTI_CR2;

EXTI_CR2_bit.PEIS = 0;//[1:0] GPIOE,配置同EXTI_CR1

EXTI_CR2_bit.TLIS = 0;//[2] TLI 0:下降沿触发 , 1:上升沿触发

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值