📄 backup1.c
字号:
//backup1.c
//SysTick function
/**
* @brief Initialize and start the SysTick counter and its interrupt.
*
* @param ticks number of ticks between two interrupts
* @return 1 = failed, 0 = successful
*
* Initialise the system tick timer and its interrupt and start the
* system tick timer / counter in free running mode to generate
* periodical interrupts.
*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | // 选择内部时钟72MHz(bit2 = 1)
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#define __NVIC_PRIO_BITS 4 /*!< STM32 uses 4 Bits for the Priority Levels */
#define SysTick_LOAD_RELOAD_Msk 0xFFFFFFul /* SysTick Reload Register Definitions */
#define SysTick_VAL_CURRENT_Msk 0xFFFFFFul /* SysTick Current Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Msk 1<<16
#define SysTick_CTRL_CLKSOURCE_Msk 1<<2
#define SysTick_CTRL_TICKINT_Msk 1<<1
#define SysTick_CTRL_ENABLE_Msk 1<<0
//========================= RCC_Clocks =============================//
//stm32f107.c
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
printf("SYSCLK_Frequency = %d\n\n",RCC_Clocks.SYSCLK_Frequency);
printf("HCLK_Frequency = %d\n\n",RCC_Clocks.HCLK_Frequency);
printf("PCLK1_Frequency = %d\n\n",RCC_Clocks.PCLK1_Frequency);
printf("PCLK2_Frequency = %d\n\n",RCC_Clocks.PCLK2_Frequency);
printf("ADCCLK_Frequency = %d\n\n",RCC_Clocks.ADCCLK_Frequency);
/* SystTick configuration: an interrupt every 10ms */
SysTick_Config(RCC_Clocks.SYSCLK_Frequency / 100); //(1/72M)*(72M/100) = 1/100
NVIC_SetPriority(SysTick_IRQn, 1);
//Result:
SYSCLK_Frequency = 72000000
HCLK_Frequency = 72000000
PCLK1_Frequency = 36000000
PCLK2_Frequency = 72000000
ADCCLK_Frequency = 36000000
//****************************** core_m3.c **********************************//
/**
* @brief Set the priority for an interrupt
*
* @param IRQn The number of the interrupt for set priority
* @param priority The priority to set
*
* Set the priority for the specified interrupt.
* The interrupt number can be positive to specify an external (device specific) interrupt,
* or negative to specify an internal (core) interrupt.
*
* Note: The priority cannot be set for every core interrupt.
*/
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
else {
NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
}
//========================= 12-15 ===================================//
//测试发送邮箱
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 1;
TxMessage.Data[0] = 0xFA;
TxMessage.StdId = InputAddr[0];
while(InputAddr[1] != 0)
{
for(i=0;i<8;i++)
{
while(((CAN1->TSR>>26)& 0x07) == 0);
TransMailbox = CAN_Transmit(CAN1, &TxMessage);
if(TransMailbox == 2)printf("===== MailBox_2 =====\n");
// while(TransMailbox == CAN_NO_MB)
// {
// TransMailbox = CAN_Transmit(CAN1, &TxMessage);
// printf("========== CAN_NO_MB. ===========\n");
// }
}
printf("\n*************** OUT ***************\n");
break;
}
//分析:
//1.验证语句 while(((CAN1->TSR>>26)& 0x07) == 0);
// 是否能够有效的判断3个发送邮箱是否有空的邮箱可用。
//2.结果表明,按照CAN_Transmit(CAN1, &TxMessage);
// 发送邮箱优先级依次为0,1,2.即先用邮箱0,若为空,则选邮箱1,以此类推。
//3.在连续发送8次的情况下,理论上,邮箱2会使用2次。
// 即0,1,2,0,1,2,0,1。
//4.若判断条件改为if(TransMailbox == 1),则printf()会发送4次;
// 因为printf()执行的时间很长,故邮箱全部变为空。
// 即0,1,0,1,0,1,0,1。
//5.若判断条件改为if(TransMailbox == 0),则printf()会发送8次;
// 即0,0,0,0,0,0,0,0。
//if(TransMailbox == 1)输出结果:
/*
*************** OUT ***************
===== MailBox_1 =====
===== MailBox_1 =====
===== MailBox_1 =====
===== MailBox_1 =====
*************** OUT ***************
===== MailBox_1 =====
===== MailBox_1 =====
===== MailBox_1 =====
===== MailBox_1 =====
*************** OUT ***************
*/
//if(TransMailbox == 2)输出结果:
/*
*************** OUT ***************
===== MailBox_2 =====
===== MailBox_2 =====
*************** OUT ***************
===== MailBox_2 =====
===== MailBox_2 =====
*************** OUT ***************
*/
/*
TxMessage.StdId = SlaveAddr;
switch(SlaveAddr)
{
case (0x001): //输入模块1
i = 0;
cnt = 8;
while(cnt)
{
cnt--;
if(RxData[i]>0xD8 && RxData[i]<0x18) //范围:-40 ~ 40
LR_Show[0] |= 1<<cnt;
else if(RxData[h] == 0x80) //值为:-128 表示模块没有接
LR_Show[0] &= 0<<cnt;
else
{
i++;
continue;
}
i++;
}
break;
}
for(i=0;i<6;i++)
TxMessage.Data[i] = LR_Show[i];
CAN_Transmit(CAN2, &TxMessage);
*/
//=================== 11-24 ====================//
// if(tim_cnt%600 == 0)
// printf("\nMasterAddr = 0x%X\n",MasterAddr);
//说明:
// 以下程序结构不可靠。因为CAN1会接收到不同模块的数据。于是,RxMessage结构体的信息可能
//会被很快的刷新。于是,前面的if()语句和后面的if()语句,条件很可能会改变,那么数据便可能
//会丢失。
// 还有一个问题,对标志位等数据清零,不能放在所有程序的最后面。比如,if(can_flag1==1)
//执行一些语句,但是在此段程序后面,才发生中断,那么can_flag1 = 1后,还没有执行语句,便
//又被清零,这种情况是不完善的。
//
// TxMessage.StdId = MasterAddr;
if((RxMessage.StdId & 0xFF)== 0x00)
{
if(startflg == 1)
{
// TxMessage.StdId = MasterAddr0;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
}
}
else if((RxMessage.StdId & 0xFF)== 0x01) //标识符低8位为1表示数据为按键值
{
TxMessage.StdId = MasterAddr1;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 4;
}
else if((RxMessage.StdId & 0xFF)== 0x02) //标识符低8位为2表示数据为增益值
{
TxMessage.StdId = MasterAddr2;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 6;
}
else
;
/*
switch(MasterAddr)
{
//ID: 0x101 - 0x501 表示5个模块按键状态(标识符:0x00表示远程帧返回值)
case (0x100):
break;
case (0x200):
break;
case (0x300):
break;
case (0x400):
break;
case (0x500):
break;
default:
break;
}
*/
// if(((MasterAddr & 0xFF)== 0x00))
if(MasterAddr)
{
if(startflg == 1)
CAN_Transmit(CAN1,&TxMessage);
}
else if(((MasterAddr & 0xFF)== 0x01)) //标识符低8位为1表示数据为按键值
{
// if(can_flag == 1) //||(tim_cnt%250==0)
CAN_Transmit(CAN1, &TxMessage);
}
else if((MasterAddr & 0xFF)== 0x02)
{
TxMessage.Data[5] = LR_Show[5];
CAN_Transmit(CAN2, &TxMessage);
}
else
{
MasterAddr = 0; //若不是指定标识符,则清零
}
//下面的程序,是比较稳定可靠的。
if((MasterAddr1 != 0)) //标识符低8位为1表示数据为按键值
{
TxMessage.StdId = MasterAddr1;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 4;
switch(MasterAddr1)
{
//ID: 0x101 - 0x501 表示5个模块按键状态(标识符:0x01表示按键值)
case (0x101):
h = 0;
for(i=0;i<4;i++)
{
cnt = 6;
while(cnt)
{
cnt--;
if(((KeyData[i]>>cnt) & 0x01) == 0x01)
KeyDataBK[i] ^= 1<<cnt;
}
TxMessage.Data[h] = KeyDataBK[i];
h++;
// if(can_flag1 == 1)
// printf("KeyDataBK[%d] = 0x%X\n",i,KeyDataBK[i]);
}
// if(can_flag1 == 1)
{
// printf("---------------------------\n");
// if((can_flag1 == 1) || (tim_cnt%250 == 0))
CAN_Transmit(CAN1, &TxMessage);
}
can_flag1 = 0;
MasterAddr1 = 0;
for(i=0;i<20;i++)
KeyData[i] = 0x0;
break;
}}
//stm32f10x_it.c
/*
TxMessage.StdId = 0x101;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 4;
TxMessage.Data[0] = 0xF0;
TxMessage.Data[1] = 0xF1;
TxMessage.Data[2] = 0xF2;
TxMessage.Data[3] = 0xF3;
CAN_Transmit(CAN1, &TxMessage);
}
*/
// for(j=0;j<4;j++)
// printf("KeyData[%d] = 0x%X\n",j,KeyData[j]);
// printf("\n");
// KeyData[j] = RxMessage.Data[j];
if(InputFlag == 1)
{
TxMessage2.RTR = CAN_RTR_DATA;
TxMessage2.IDE = CAN_ID_STD;
TxMessage2.DLC = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -