- #include "can.h"
- #include "key.h"
- #ifdef CAN_RX0_INT_ENABLE
- uint8_t CAN_RX_BUFF[8];
- #endif
- uint8_t ShowData[5] = {'0', '0', 0};
- uint8_t CAN_SendData[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}; //最后两位用来存放发送ID和接收ID
- uint8_t *Mode;
- const uint8_t CAN_ModeNormal[9] = {"正常模式"};
- const uint8_t CAN_ModeLoopBack[9] = {"环回模式"};
- /****************************************************************************
- * Function Name : CAN1_NVIC_Config
- * Description : Main program.
- * Input : None
- * Output : None
- * Return : None
- ****************************************************************************/
- static void CAN1_NVIC_Config(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- /* 使能接收的中断和中断优先级 */
- NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); //FIFO0消息挂号中断允许.
- }
- /****************************************************************************
- * Function Name : CAN1_Config
- * Description : 初始化CAN,波特率设置为450K
- * Input : mode:用来选择要使用的工作模式:主要有四种工作模式:1、正常
- * * 模式:CAN_Mode_Normal;2、CAN_Mode_Silent :静默模式;3、环
- * * 回模式:CAN_Mode_LoopBack;4、静默环回模式:CAN_Mode_Silent
- * * _LoopBack。
- * Output : None
- * Return : None
- ****************************************************************************/
- void CAN1_Config(uint8_t mode)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- CAN_InitTypeDef CAN_InitStructure;
- /* 初始化IO口 */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PA12
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //PA11
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /***************************************************************************/
- /********************* CAN设置和初始化 *************************************/
- /***************************************************************************/
- /* 打开时钟使能 */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
- /* 初始化CAN的参数 */
- CAN_DeInit(CAN1);
- CAN_StructInit(&CAN_InitStructure);
- /* CAN 参数初始化 */
- CAN_InitStructure.CAN_TTCM = DISABLE; //失能时间触发模式
- CAN_InitStructure.CAN_ABOM = DISABLE; //失能自动离线管理
- CAN_InitStructure.CAN_AWUM = DISABLE; //失能睡眠模式通过软件唤醒
- CAN_InitStructure.CAN_NART = DISABLE; //失能非自动重传输模式(也就是会自动重传输)
- CAN_InitStructure.CAN_RFLM = DISABLE; //失能接收FIFO锁定模式,新数据会覆盖旧数据
- CAN_InitStructure.CAN_TXFP = DISABLE; //优先级由报文标识符决定
- CAN_InitStructure.CAN_Mode = mode; //有普通模式和拓展模式
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //重新同步跳跃宽度 1 个时间单位
- /* 波特率设置, 当APB1的时钟频率是36MHZ的时候。 波特率的公式为: */
- /* 波特率(Kpbs) = 36M / ((CAN_BS1 + CAN_BS2 + 1) * CAN_Prescaler) */
- CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq; //时间段 1 为8 个时间单位
- CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq; //时间段 2 为7 个时间单位
- CAN_InitStructure.CAN_Prescaler = 5;
- CAN_Init(CAN1, &CAN_InitStructure);
- #ifdef CAN_RX0_INT_ENABLE
- CAN1_NVIC_Config();
- #endif
- }
- /****************************************************************************
- * Function Name : CAN1_SendMesg
- * Description : 发送一个报文
- * Input : id:发送的ID。
- * * len:发送的数据长度(注意发送数据长度不能超过8个字节)
- * * dat:存放数据的指针
- * Output : None
- * Return : None
- ****************************************************************************/
- void CAN1_SendMesg(uint32_t id, uint8_t len, uint8_t *dat)
- {
- uint16_t i = 0;
- CanTxMsg TxMessage;
- /* 一次发送只能发送8个字节 */
- if(len > 8)
- {
- return ;
- }
- /* 配置邮箱:设置标识符,数据长度和待发送数据 */
- TxMessage.StdId = (id & 0x7FF); //标准帧ID11位
- TxMessage.ExtId = (id >> 11); //设置扩展标示符(拓展标示符有29位)
- TxMessage.RTR = CAN_RTR_DATA; //设置为数据帧(或远程帧为CAN_RTR_Remote)
- if((id & 0x7FF) == 0x7FF) //检测是标准帧还是拓展帧(拓展帧大于11位)
- {
- TxMessage.IDE = CAN_ID_STD; //拓展ID
- }
- else
- {
- TxMessage.IDE = CAN_ID_EXT; //标准ID
- }
- TxMessage.DLC = len; //发送的数据长度
- /* 将数据放入到邮箱中 */
- for(i=0; i<len; i++)
- {
- TxMessage.Data[i] = *dat;
- dat++;
- }
-
- /* 开始传送数据 */
- CAN_Transmit(CAN1, &TxMessage);
- }
- /****************************************************************************
- * Function Name : CAN1_Config16BitFilter
- * Description : 设置CAN接收16两个标准ID(设置ID位数全部相同才能够通过)
- * Input : id1:要接收的一个ID
- * * id2:要接收的一个ID
- * Output : None
- * Return : None
- ****************************************************************************/
- void CAN1_Config16BitFilter(uint16_t id1, uint16_t id2)
- {
- CAN_FilterInitTypeDef CAN_FilterInitStructure;
- uint16_t mask = 0xFFFF;
- /* CAN filter init 屏蔽寄存器初始化 */
- CAN_FilterInitStructure.CAN_FilterNumber = 1; //过滤器1
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//ID模式
- /* 寄存器组设置为16位 */
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
- CAN_FilterInitStructure.CAN_FilterIdHigh = (id1 << 5); //要接收的ID标示符1
- CAN_FilterInitStructure.CAN_FilterIdLow = (id2 << 5); //要接收的ID标示符2
- /* 设置为所有ID位都要相同才接收 */
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (mask << 5); //MASK
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = (mask << 5);
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; //FIFO0
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器1
- CAN_FilterInit(&CAN_FilterInitStructure);
- }
- /****************************************************************************
- * Function Name : CAN1_Config32BitFilter
- * Description : 设置一个拓展ID的接收
- * Input : id:要接收的ID
- * Output : None
- * Return : None
- ****************************************************************************/
- void CAN1_Config32BitFilter(uint32_t id)
- {
- uint32_t mask = 0xFFFFFFFF;
- CAN_FilterInitTypeDef CAN_FilterInitStructure;
- /* CAN filter init 屏蔽寄存器初始化 */
- CAN_FilterInitStructure.CAN_FilterNumber = 1; //过滤器1
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//ID模式
- /* 寄存器组设置为32位 */
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
- CAN_FilterInitStructure.CAN_FilterIdHigh = (id >> 13); //要接收的ID标示符1
- CAN_FilterInitStructure.CAN_FilterIdLow = (id << 3 ) | 4;//要接收的ID标示符2
- /* 设置为所有ID位都要相同才接收 */
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = mask >> 13; //MASK
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = (mask << 3) | 4;
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; //FIFO0
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器1
- CAN_FilterInit(&CAN_FilterInitStructure);
- }
- /****************************************************************************
- * Function Name : CAN1_ReceiveMesg
- * Description : 接收一个报文
- * Input : receiveBuff:接收数据的数组指针
- * Output : None
- * Return : None
- ****************************************************************************/
- void CAN1_ReceiveMesg(uint8_t *receiveBuff)
- {
- uint8_t i = 0;
- CanRxMsg RxMessage; //设置接收邮箱
- if((CAN_MessagePending(CAN1, CAN_FIFO0) != 0)) //检查FIFO0里面是否有数据
- {
- CAN_Receive(CAN1,CAN_FIFO0,&RxMessage); //读取FIFO0里面的数据
- for(i=0; i<RxMessage.DLC; i++) //将读取到的数据位赋给CAN_RXSBUF
- {
- *receiveBuff = RxMessage.Data[i];
- receiveBuff++;
- }
- }
- }
- /****************************************************************************
- * Function Name : USB_LP_CAN1_RX0_IRQHandler
- * Description : FIFO0接收一个报文数据数据(最大8个字节)
- * Input : None
- * Output : None
- * Return : None
- ****************************************************************************/
- #ifdef CAN_RX0_INT_ENABLE
- void USB_LP_CAN1_RX0_IRQHandler(void)
- {
- CAN1_ReceiveMesg(CAN_RX_BUFF);
- }
- #endif
- void GUI_DisplayData(uint8_t num)
- {
- uint8_t addr;
-
- for(addr=0; addr<10; addr++)
- {
- if(addr < 8)
- {
- /* 如果接收到数据,显示数据 */
- /* 将读取到的16位数据转换成可以显示的ASCII码 */
- ShowData[0] = CAN_RX_BUFF[addr] >> 4;
- if(ShowData[0] > 9)
- {
- ShowData[0] += '7'; //当大于9时,用ABCDEF来表示
- }
- else
- {
- ShowData[0] += '0';
- }
- ShowData[1] = CAN_RX_BUFF[addr] & 0x0F;
- if(ShowData[1] > 9)
- {
- ShowData[1] += '7'; //当大于9时,用ABCDEF来表示
- }
- else
- {
- ShowData[1] += '0';
- }
- /* 显示接收到的数据 */
- GUI_Show12Char(208, (60 + addr * 20), ShowData, RED, BLACK);
- }
-
- /* 将要发送的16位数据转换成可以显示的ASCII码 */
- ShowData[0] = CAN_SendData[addr] >> 4;
- if(ShowData[0] > 9)
- {
- ShowData[0] += '7'; //当大于9时,用ABCDEF来表示
- }
- else
- {
- ShowData[0] += '0';
- }
- ShowData[1] = CAN_SendData[addr] & 0x0F;
- if(ShowData[1] > 9)
- {
- ShowData[1] += '7'; //当大于9时,用ABCDEF来表示
- }
- else
- {
- ShowData[1] += '0';
- }
- if(addr < 8)
- {
- /* 显示发送数据,选择高亮位置 */
- if(num == addr)
- {
- GUI_Show12Char(88, (60 + addr * 20), ShowData, GREEN, BLACK);
- }
- else
- {
- GUI_Show12Char(88, (60 + addr * 20), ShowData, RED, BLACK);
- }
- }
- else //显示ID部分
- {
- if(addr == 8)
- {
- if(num == 8)
- {
- GUI_Show12Char(52, 40, ShowData, GREEN, BLACK);
- }
- else
- {
- GUI_Show12Char(52, 40, ShowData, RED, BLACK);
- }
- }
- if(addr == 9)
- {
- if(num == 9)
- {
- GUI_Show12Char(176, 40, ShowData, GREEN, BLACK);
- }
- else
- {
- GUI_Show12Char(176, 40, ShowData, RED, BLACK);
- }
- }
- }
- }
- if(num > 9)
- {
- GUI_Show12Char(104, 20, Mode, GREEN, BLACK);
- }
- else
- {
- GUI_Show12Char(104, 20, Mode, RED, BLACK);
- }
- }
- void CAN_pros()
- {
- uint8_t m, receiveId,canMode;
- m = 10;
- canMode = 1; //要设置canMode不等于CAN_SendData[10],以便进入循环一开始就初始化
- TFT_ClearScreen(BLACK);
- delay_ms(10);
- while(1)
- {
- if(TouchData.lcdx>72&&TouchData.lcdx<112&&TouchData.lcdy>268&&TouchData.lcdy<306)
- {
-
- GUI_Show12Char(76, 0, "CAN通信实验", RED, BLACK);
- /* 显示工作模式 */
- GUI_Show12Char(0, 20, "CAN工作模式:", RED, BLACK);
-
- /* 显示发送接收ID */
- GUI_Show12Char(0, 40, "发送ID:", RED, BLACK);
- GUI_Show12Char(120, 40, "接收ID:", RED, BLACK);
-
- /* 显示发送和接收数据的8位数 */
- GUI_Show12Char(0, 60, "发送第一位:", RED, BLACK);
- GUI_Show12Char(120, 60, "接收第一位:", RED, BLACK);
- GUI_Show12Char(0, 80, "发送第二位:", RED, BLACK);
- GUI_Show12Char(120, 80, "接收第二位:", RED, BLACK);
- GUI_Show12Char(0, 100, "发送第三位:", RED, BLACK);
- GUI_Show12Char(120, 100, "接收第三位:", RED, BLACK);
- GUI_Show12Char(0, 120, "发送第四位:", RED, BLACK);
- GUI_Show12Char(120, 120, "接收第四位:", RED, BLACK);
- GUI_Show12Char(0, 140, "发送第五位:", RED, BLACK);
- GUI_Show12Char(120, 140, "接收第五位:", RED, BLACK);
- GUI_Show12Char(0, 160, "发送第六位:", RED, BLACK);
- GUI_Show12Char(120, 160, "接收第六位:", RED, BLACK);
- GUI_Show12Char(0, 180, "发送第七位:", RED, BLACK);
- GUI_Show12Char(120, 180, "接收第七位:", RED, BLACK);
- GUI_Show12Char(0, 200, "发送第八位:", RED, BLACK);
- GUI_Show12Char(120, 200, "接收第八位:", RED, BLACK);
- GUI_Show12Char(0, 220, "上键:高亮部分加一", BLUE, BLACK);
- GUI_Show12Char(0, 240, "下键:高亮部分减一", BLUE, BLACK);
- GUI_Show12Char(0, 260, "左键:高亮部分向下移动一位", BLUE, BLACK);
- GUI_Show12Char(0, 280, "右键:发送数据", BLUE, BLACK);
- GUI_Show12Char(0, 300, "注:波特率为450K", BLUE, BLACK);
- GUI_Show12Char(TFT_XMAX-16*2,TFT_YMAX-16,"返回",YELLOW,BLACK);
- TouchData.lcdx=0;
- TouchData.lcdy=0;
- }
- TOUCH_Scan();
- /* 修改模式 */
- if(canMode != CAN_SendData[10] )
- {
- canMode = CAN_SendData[10];
- if(CAN_SendData[10])
- {
- CAN1_Config(CAN_Mode_Normal);
- Mode = (uint8_t *)CAN_ModeNormal;
- }
- else
- {
- CAN1_Config(CAN_Mode_LoopBack);
- Mode = (uint8_t *)CAN_ModeLoopBack;
- }
- CAN1_Config16BitFilter(CAN_SendData[9], 0x00);
- }
- /* 如果接收ID改变,就重新设置接收ID */
- if(receiveId != CAN_SendData[9])
- {
- receiveId = CAN_SendData[9];
- if(receiveId != 0x00)
- {
- CAN1_Config16BitFilter(CAN_SendData[9], 0x00);
- }
- }
- /* 显示数据 */
- GUI_DisplayData(m);
- if(k_up==1) //判断按键k_up是否按下
- {
- delay_ms(10); //消抖处理
- if(k_up==1) //再次判断按键k_up是否按下
- {
- if(m == 10)
- {
- CAN_SendData[10] = ~CAN_SendData[10];
- }
- else
- {
- CAN_SendData[m]++;
- }
- GUI_Show12Char(175, 20, "等待发送", RED, BLACK);
- }
- while(k_up); //等待按键松开
- }
- if(k_down==0)
- {
- delay_ms(10);
- if(k_down==0)
- {
- if(m == 10)
- {
- CAN_SendData[10] = ~CAN_SendData[10];
- }
- else
- {
- CAN_SendData[m]--;
- }
- GUI_Show12Char(175, 20, "等待发送", RED, BLACK);
- }
- while(!k_down);
- }
- if(k_left==0)
- {
- delay_ms(10);
- if(k_left==0)
- {
- if(m == 10)
- {
- m = 0;
- }
- else
- {
- m++;
- }
- }
- while(!k_left);
- }
- if(k_right==0)
- {
- delay_ms(10);
- if(k_right==0)
- {
- CAN1_SendMesg(CAN_SendData[8], 8, CAN_SendData);//发送数据
- GUI_Show12Char(175, 20, "发送成功", BLUE, BLACK);
- }
- while(!k_right);
- }
- if(TouchData.lcdx>TFT_XMAX-16*2&&TouchData.lcdx<TFT_XMAX&&TouchData.lcdy>TFT_YMAX-16&&TouchData.lcdy<TFT_YMAX)
- {
- GUI_DisplayInit();
- break;
- }
- TOUCH_Scan();
- }
- }