当前位置:网站首页>Can communication experiment between C and C

Can communication experiment between C and C

2022-06-25 00:45:00 Rodinia lava

C# Of message Comparison with single chip microcomputer :

    public struct MESSAGESTRUCT
    {
    
        public string name;            // name 
        public int id;                 //ID
        public string comment;         // explain 
        public int dlc;                // Number of bytes 
        public string type;            //J1939,  Wake up the , standard 

        public Dictionary<string, SIGNALSTRUCT> dicsignal;// Locate the signal according to the signal name 
        public Kvadblib.MessageHnd mh; // Handle of current message 
    }

    u8 Can_Send_Msg(u8* msg, u8 len)
    {
    
        u8 mbox;
        u16 i = 0;
        CanTxMsg TxMessage;
        TxMessage.StdId = 0x12;         //  Standard Identifier  
        TxMessage.ExtId = 0x12;         //  Set identifier extension  
        TxMessage.IDE = CAN_Id_Standard;    //  Standard frame 
        TxMessage.RTR = CAN_RTR_Data;       //  Data frame 
        TxMessage.DLC = len;                //  The length of data to be sent 
        for (i = 0; i < len; i++)
            TxMessage.Data[i] = msg[i];
        mbox = CAN_Transmit(CAN1, &TxMessage);
        i = 0;
        while ((CAN_TransmitStatus(CAN1, mbox) == CAN_TxStatus_Failed) && (i < 0XFFF)) i++; // Wait for the end of sending 
        if (i >= 0XFFF) return 1;
        return 0;
    }

    typedef struct
    {
    
      uint32_t StdId;  /*!< Specifies the standard identifier.  Standard Identifier  This parameter can be a value between 0 to 0x7FF. */

    uint32_t ExtId;  /*!< Specifies the extended identifier.  Set the extension identifier  This parameter can be a value between 0 to 0x1FFFFFFF. */

    uint8_t IDE;     /*!< Specifies the type of identifier for the message that will be transmitted. This parameter can be a value of @ref CAN_identifier_type */

    uint8_t RTR;     /*!< Specifies the type of frame for the message that will be transmitted. This parameter can be a value of @ref CAN_remote_transmission_request */

    uint8_t DLC;     /*!< Specifies the length of the frame that will be transmitted. This parameter can be a value between 0 to 8 */

    uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0 to 0xFF. */
}
CanTxMsg;
using canlibCLSNET;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static canlibCLSNET.Canlib;

namespace CanDemon
{
    
    public partial class FrmMain : Form
    {
    
        public FrmMain()
        {
    
            InitializeComponent();

            //Canlib.canInitializeLibrary();// Read information , initialization 
            this.btnRefresh_Click(null, null);  // Refresh 
            this.cmb_Baud.DataSource = new List<string>() {
     "125000", "250000", "500000", "1000000" };
            this.cmb_Baud.SelectedIndex = 0;
        }

        private int handle = 0;
        private canStatus canStatus;
        private int chanelCount = 0; // The channel number 
        CancellationTokenSource cts = new CancellationTokenSource();

        private void btnRefresh_Click(object sender, EventArgs e)
        {
    
            
            canStatus = Canlib.canGetNumberOfChannels(out chanelCount);// obtain can All channels 
            if (canStatus!= canStatus.canOK)
            {
    
                HandleError("canGetNumberOfChannels", canStatus);
            }

            cmb_Channel.Items.Clear();
            for (int i = 0; i < chanelCount; i++)
            {
    
                object obj;

                // Get channel name :canCHANNELDATA_CHANNEL_NAME
                canStatus status = canGetChannelData(i, canCHANNELDATA_CHANNEL_NAME,out obj);//channel Number ,item Number ,buffer data 
                string strout = obj.ToString(); // convert to obj type   Get channel name 

                // product ID  canCHANNELDATA_CARD_SERIAL_NO
                status = canGetChannelData(i, canCHANNELDATA_CARD_SERIAL_NO, out obj);
                string strtmp = string.Format(",{0:D6}", obj); // The data length is 6, If it is not enough, fill in the front 0

                strout += strtmp;
                cmb_Channel.Items.Add(strout);

            }
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
    
            if (this.btnOpen.Text == " open ")
            {
    
                // open 
                handle = canOpenChannel(this.cmb_Channel.SelectedIndex, canOPEN_OVERRIDE_EXCLUSIVE + canOPEN_ACCEPT_VIRTUAL);

                // set baud rate 
                canStatus = canSetBitrate(handle, Convert.ToInt32(this.cmb_Baud.Text));

                HandleError("canSetBitrate", canStatus);

                //Bus On
                canStatus = canBusOn(handle);
                if (canStatus != canStatus.canOK)
                {
    
                    HandleError("canBusOn", canStatus);
                    return;
                }
                else
                {
    
                    // Start thread reading 
                    this.btnOpen.Text = "Close";

                    Task.Run(async () =>
                    {
    
                        while (!cts.IsCancellationRequested)
                        {
    
                            byte[] buffer = new byte[100];

                            //out  There is no need to define 
                            //dlc length ,flag Sign a 
                            await Task.Delay(500);
                            canStatus = canRead(handle, out int id, buffer, out int dlc, out int flag, out long time);
                            if (canStatus != canStatus.canOK)
                            {
    
                                string error = string.Empty;

                                canGetErrorText(canStatus, out error);

                                AddInfo("Receive Error:" + error);
                            }
                            else
                            {
    
                                // Successfully read 
                                byte[] result = new byte[dlc];
                                //buffer Copy to reslut
                                Array.Copy(buffer, 0, result, 0, dlc);

                                AddInfo("Receive Data:" + time.ToString() + " " + id.ToString() + GetHexStringFromByteArray(result));
                            }
                        }
                    });
                }
            }

            else
            {
    
                canClose(handle);
                this.btnOpen.Text = "Open";
            }

        }

        private void HandleError(string cmd, canStatus status)
        {
    
            if (status != canStatus.canOK) // Error status 
            {
    
                string error = string.Empty;
                canGetErrorText(status, out error);
                AddInfo($"{
      cmd} Error: {
      error}");
            }
        }

        private void AddInfo(string info)
        {
    
            if (this.listInfo.InvokeRequired)
            {
    
                this.Invoke(new Action(() =>
                {
    
                    this.listInfo.Items.Add(info);
                }));
                //this.listInfo.Invoke
            }
            else
            {
    
                this.listInfo.Items.Add(info);
            }
        }

        private string GetHexStringFromByteArray(byte[] b)
        {
    
            StringBuilder sb = new StringBuilder();
            foreach (var item in b)
            {
    
                sb.Append(item.ToString("X") + " ");
            }

            return sb.ToString().Trim();
        }


    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Kvaser.Kvadblib;

namespace CanDemon
{
    
    public enum canMSGFlag
    {
    
        canMsg_Mask = 0x00FF,
        canMsg_RTR = 0x0001,
        canMsg_STD = 0x0002,
        canMsg_EXT = 0x0004,
        canMsg_WAKEUP = 0x0008,
        canMsg_NERR = 0x0010,
        canMsg_ERROR_FRAME = 0x0020,
        canMsg_TXACK = 0x0040,
        canMsg_TXRQ = 0x0080F,
    }


    public struct SIGNALSTRUCT
    {
    
        public string name;            // name 
        public string comment;         // notes 
        public string unit;            // Company 
        public string encooding;       // code 
        public string type;            // type 
        public double minvaluelimit;   // minimum value 
        public double maxvaluelimit;   // Maximum 
        public double factor;          // coefficient 
        public double offset;          // Offset 
        public int startbit;           // Start bit 
        public int bitlength;          // Bit length 
        public Kvadblib.SignalHnd sh;  // Handle to the current signal 
    }
    public struct MESSAGESTRUCT
    {
    
        public string name;            // name 
        public int id;                 //ID
        public string comment;         // explain 
        public int dlc;                // Number of bytes 
        public string type;            //J1939,  Wake up the , standard 

        public Dictionary<string, SIGNALSTRUCT> dicsignal;// Locate the signal according to the signal name   One to many , There are many. signnal
        public Kvadblib.MessageHnd mh; // Handle of current message 
    }
    public class canDbcReader
    {
    
        Kvadblib.Hnd dh = new Kvadblib.Hnd();
        Kvadblib.MessageHnd mh = new Kvadblib.MessageHnd();
        Kvadblib.SignalHnd sh = new Kvadblib.SignalHnd();
        Kvadblib.Status status;

        //08
        public Dictionary<int, MESSAGESTRUCT> dicMessage = new Dictionary<int, MESSAGESTRUCT>(); //canDbcReader There are multiple Message

        public Dictionary<string, int> dicSigNameID = new Dictionary<string, int>();

        public canDbcReader()
        {
    
            dh = new Kvadblib.Hnd();
            status = Kvadblib.Open(out dh);
        }

        #region  Import dbc file , The relevant data is stored in the structure of the dictionary 
        public bool ImportDbc(string strDbc)
        {
    
            #region  Clear the original data 

            foreach (MESSAGESTRUCT item in dicMessage.Values)
            {
    
                item.dicsignal.Clear();
            }
            dicMessage.Clear();

            dicSigNameID.Clear();

            #endregion

            try
            {
    
                // open dbc file 
                status = Kvadblib.ReadFile(dh, strDbc);

                if (status != Kvadblib.Status.OK)
                    return false;


                status = Kvadblib.GetFirstMsg(dh, out mh);
                while (status == Kvadblib.Status.OK)// Loop through the message , And the signal below the message 
                {
    
                    MESSAGESTRUCT message = new MESSAGESTRUCT();
                    message.dicsignal = new Dictionary<string, SIGNALSTRUCT>();

                    if (!GetMessageInfo(mh, out message))

                        return false;

                    dicMessage.Add(message.id, message);

                    status = Kvadblib.GetNextMsg(dh, out mh);
                }
                return true;
            }
            catch
            {
    
                return false;
            }
        }
        #endregion

        #region  According to the signal handle sh Get signal information 
        private void GetSignalInfo(Kvadblib.SignalHnd sh, out SIGNALSTRUCT sig)
        {
    
            SIGNALSTRUCT signal = new SIGNALSTRUCT();
            signal.sh = sh;                                             // Signal handle 
            status = Kvadblib.GetSignalName(sh, out signal.name);       // Signal name 
            status = Kvadblib.GetSignalComment(sh, out signal.comment); // Signal description 
            status = Kvadblib.GetSignalUnit(sh, out signal.unit);       // Signal unit 
            Kvadblib.SignalEncoding se;                                 // Encoding mode ,inter or  motorola
            status = Kvadblib.GetSignalEncoding(sh, out se);
            if (se == Kvadblib.SignalEncoding.Intel)
                signal.encooding = "Inter";
            else if (se == Kvadblib.SignalEncoding.Motorola)
                signal.encooding = "Motorola";
            Kvadblib.SignalType st;                                     // Signal data type  
            status = Kvadblib.GetSignalRepresentationType(sh, out st);
            switch (st)
            {
    
                case Kvadblib.SignalType.Signed:
                    signal.type = "Signed";
                    break;
                case Kvadblib.SignalType.Unsigned:
                    signal.type = "Unsigned";
                    break;
                case Kvadblib.SignalType.Double:
                    signal.type = "Double";
                    break;
                case Kvadblib.SignalType.Float:
                    signal.type = "Float";
                    break;
                case Kvadblib.SignalType.Invalid:
                    signal.type = "Invalid";
                    break;
            }
            status = Kvadblib.GetSignalValueLimits(sh, out signal.minvaluelimit, out signal.maxvaluelimit);// Range of maximum and minimum signal values 
            status = Kvadblib.GetSignalValueScaling(sh, out signal.factor, out signal.offset);// Factors and offsets 
            status = Kvadblib.GetSignalValueSize(sh, out signal.startbit, out signal.bitlength);// Start bit , Bit length 
            sig = signal;
        }
        #endregion

        #region  According to the message handle mh Get message information 
        private bool GetMessageInfo(Kvadblib.MessageHnd mh, out MESSAGESTRUCT msg)
        {
    
            MESSAGESTRUCT message = new MESSAGESTRUCT();
            message.dicsignal = new Dictionary<string, SIGNALSTRUCT>();
            try
            {
    
                Kvadblib.MESSAGE km;
                status = Kvadblib.GetMsgId(mh, out message.id, out km);//ID And frame type 

                switch (km)
                {
    
                    case Kvadblib.MESSAGE.EXT:
                        message.type = " Expand ";
                        message.id = message.id & 0x1FFFFFFF;
                        break;
                    case Kvadblib.MESSAGE.J1939:
                        message.type = "J1939";
                        break;
                    case Kvadblib.MESSAGE.WAKEUP:
                        message.type = " Wake up frame ";
                        break;
                    default:
                        message.type = " standard ";
                        message.id = message.id & 0x1FFFFFFF;
                        break;
                }
                status = Kvadblib.GetMsgName(mh, out message.name);// Message name 
                status = Kvadblib.GetMsgDlc(mh, out message.dlc);// packet length 
                status = Kvadblib.GetMsgComment(mh, out message.comment);// Message description 
                message.mh = mh;// Current handle 

                SIGNALSTRUCT signal = new SIGNALSTRUCT();
                Kvadblib.SignalHnd sh = new Kvadblib.SignalHnd();
                status = Kvadblib.GetFirstSignal(message.mh, out sh);
                while (status == Kvadblib.Status.OK)
                {
    

                    GetSignalInfo(sh, out signal);
                    dicSigNameID.Add(signal.name, message.id);
                    message.dicsignal.Add(signal.name, signal);
                    status = Kvadblib.GetNextSignal(mh, out sh);
                }
                msg = message;
                return true;
            }
            catch
            {
    
                msg = message;
                return false;
            }
        }
        #endregion

        #region  Fill the message with physical quantity or original value 
        // Fill the message with the original value of the signal 
        public bool StoreSignalValueRaw(SIGNALSTRUCT signal, byte[] candata, int length, int raw)
        {
    
            status = Kvadblib.StoreSignalValueRaw(signal.sh, candata, candata.Length, raw);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }
        // Fill the message with the physical value of the signal 

        public bool StoreSignalValuePhys(SIGNALSTRUCT signal, byte[] candata, int length, double phys)
        {
    
            status = Kvadblib.StoreSignalValuePhys(signal.sh, candata, candata.Length, phys);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }

        #endregion

        #region  Acquire physical quantities according to signals and original values 
        // transformation CAN Data to floating point physical values 
        public bool GetSignalValueFloat(SIGNALSTRUCT signal, byte[] candata, int length, out double value)
        {
    
            status = Kvadblib.GetSignalValueFloat(signal.sh, out value, candata, candata.Length);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }

        // transformation CAN Data to integer physical value 
        public bool GetSignalValueInteger(SIGNALSTRUCT signal, byte[] candata, int length, out int value)
        {
    
            status = Kvadblib.GetSignalValueInteger(signal.sh, out value, candata, candata.Length);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }

        //2 transformation CAN Data to enumerated physical values 
        public bool GetSignalValueEnum(SIGNALSTRUCT signal, byte[] candata, int length, out string value)
        {
    
            status = Kvadblib.GetSignalValueEnum(signal.sh, out value, candata, candata.Length);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }
        #endregion
    }
}

namespace AXEBMSPro
{
    
    public enum canMSGFlag
    {
    
        canMsg_Mask = 0x00FF,
        canMsg_RTR = 0x0001,
        canMsg_STD = 0x0002,
        canMsg_EXT = 0x0004,
        canMsg_WAKEUP = 0x0008,
        canMsg_NERR = 0x0010,
        canMsg_ERROR_FRAME = 0x0020,
        canMsg_TXACK = 0x0040,
        canMsg_TXRQ = 0x0080F,
    }


    public struct SIGNALSTRUCT
    {
    
        public string name;            // name 
        public string comment;         // notes 
        public string unit;            // Company 
        public string encooding;       // code 
        public string type;            // type 
        public double minvaluelimit;   // minimum value 
        public double maxvaluelimit;   // Maximum 
        public double factor;          // coefficient 
        public double offset;          // Offset 
        public int startbit;           // Start bit 
        public int bitlength;          // Bit length 
        public Kvadblib.SignalHnd sh;  // Handle to the current signal 
    }
    public struct MESSAGESTRUCT
    {
    
        public string name;            // name 
        public int id;                 //ID
        public string comment;         // explain 
        public int dlc;                // Number of bytes 
        public string type;            //J1939,  Wake up the , standard 

        public Dictionary<string, SIGNALSTRUCT> dicsignal;// Locate the signal according to the signal name 
        public Kvadblib.MessageHnd mh; // Handle of current message 
    }
    public class canDbcReader
    {
    
        Kvadblib.Hnd dh = new Kvadblib.Hnd();
        Kvadblib.MessageHnd mh = new Kvadblib.MessageHnd();
        Kvadblib.SignalHnd sh = new Kvadblib.SignalHnd();
        Kvadblib.Status status;

        public Dictionary<int, MESSAGESTRUCT> dicMessage = new Dictionary<int, MESSAGESTRUCT>();

        public Dictionary<string, int> dicSigNameID = new Dictionary<string, int>();

        public canDbcReader()
        {
    
            dh = new Kvadblib.Hnd();
            status = Kvadblib.Open(out dh);
        }

        #region  Import dbc file , The relevant data is stored in the structure of the dictionary 
        public bool ImportDbc(string strDbc)
        {
    
            #region  Clear the original data 

            foreach (MESSAGESTRUCT item in dicMessage.Values)
            {
    
                item.dicsignal.Clear();
            }
            dicMessage.Clear();

            dicSigNameID.Clear();

            #endregion

            try
            {
    
                // open dbc file 
                status = Kvadblib.ReadFile(dh, strDbc);

                if (status != Kvadblib.Status.OK)
                    return false;


                status = Kvadblib.GetFirstMsg(dh, out mh);
                while (status == Kvadblib.Status.OK)// Loop through the message , And the signal below the message 
                {
    
                    MESSAGESTRUCT message = new MESSAGESTRUCT();
                    message.dicsignal = new Dictionary<string, SIGNALSTRUCT>();

                    if (!GetMessageInfo(mh, out message))

                        return false;

                    dicMessage.Add(message.id, message);

                    status = Kvadblib.GetNextMsg(dh, out mh);
                }
                return true;
            }
            catch
            {
    
                return false;
            }
        }
        #endregion

        #region  According to the signal handle sh Get signal information 
        private void GetSignalInfo(Kvadblib.SignalHnd sh, out SIGNALSTRUCT sig)
        {
    
            SIGNALSTRUCT signal = new SIGNALSTRUCT();
            signal.sh = sh;                                             // Signal handle 
            status = Kvadblib.GetSignalName(sh, out signal.name);       // Signal name 
            status = Kvadblib.GetSignalComment(sh, out signal.comment); // Signal description 
            status = Kvadblib.GetSignalUnit(sh, out signal.unit);       // Signal unit 
            Kvadblib.SignalEncoding se;                                 // Encoding mode ,inter or  motorola
            status = Kvadblib.GetSignalEncoding(sh, out se);
            if (se == Kvadblib.SignalEncoding.Intel)
                signal.encooding = "Inter";
            else if (se == Kvadblib.SignalEncoding.Motorola)
                signal.encooding = "Motorola";
            Kvadblib.SignalType st;                                     // Signal data type  
            status = Kvadblib.GetSignalRepresentationType(sh, out st);
            switch (st)
            {
    
                case Kvadblib.SignalType.Signed:
                    signal.type = "Signed";
                    break;
                case Kvadblib.SignalType.Unsigned:
                    signal.type = "Unsigned";
                    break;
                case Kvadblib.SignalType.Double:
                    signal.type = "Double";
                    break;
                case Kvadblib.SignalType.Float:
                    signal.type = "Float";
                    break;
                case Kvadblib.SignalType.Invalid:
                    signal.type = "Invalid";
                    break;
            }
            status = Kvadblib.GetSignalValueLimits(sh, out signal.minvaluelimit, out signal.maxvaluelimit);// Range of maximum and minimum signal values 
            status = Kvadblib.GetSignalValueScaling(sh, out signal.factor, out signal.offset);// Factors and offsets 
            status = Kvadblib.GetSignalValueSize(sh, out signal.startbit, out signal.bitlength);// Start bit , Bit length 
            sig = signal;
        }
        #endregion

        #region  According to the message handle mh Get message information 
        private bool GetMessageInfo(Kvadblib.MessageHnd mh, out MESSAGESTRUCT msg)
        {
    
            MESSAGESTRUCT message = new MESSAGESTRUCT();
            message.dicsignal = new Dictionary<string, SIGNALSTRUCT>();
            try
            {
    
                Kvadblib.MESSAGE km;
                status = Kvadblib.GetMsgId(mh, out message.id, out km);//ID And frame type 

                switch (km)
                {
    
                    case Kvadblib.MESSAGE.EXT:
                        message.type = " Expand ";
                        message.id = message.id & 0x1FFFFFFF;
                        break;
                    case Kvadblib.MESSAGE.J1939:
                        message.type = "J1939";
                        break;
                    case Kvadblib.MESSAGE.WAKEUP:
                        message.type = " Wake up frame ";
                        break;
                    default:
                        message.type = " standard ";
                        message.id = message.id & 0x1FFFFFFF;
                        break;
                }
                status = Kvadblib.GetMsgName(mh, out message.name);// Message name 
                status = Kvadblib.GetMsgDlc(mh, out message.dlc);// packet length 
                status = Kvadblib.GetMsgComment(mh, out message.comment);// Message description 
                message.mh = mh;// Current handle 

                SIGNALSTRUCT signal = new SIGNALSTRUCT();
                Kvadblib.SignalHnd sh = new Kvadblib.SignalHnd();
                status = Kvadblib.GetFirstSignal(message.mh, out sh);
                while (status == Kvadblib.Status.OK)
                {
    
                  
                    GetSignalInfo(sh, out signal);
                    dicSigNameID.Add(signal.name, message.id);
                    message.dicsignal.Add(signal.name, signal);
                    status = Kvadblib.GetNextSignal(mh, out sh);
                }
                msg = message;
                return true;
            }
            catch
            {
    
                msg = message;
                return false;
            }
        }
        #endregion

        #region  Fill the message with physical quantity or original value 
        // Fill the message with the original value of the signal 
        public bool StoreSignalValueRaw(SIGNALSTRUCT signal, byte[] candata, int length, int raw)
        {
    
            status = Kvadblib.StoreSignalValueRaw(signal.sh, candata, candata.Length, raw);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }
        // Fill the message with the physical value of the signal 

        public bool StoreSignalValuePhys(SIGNALSTRUCT signal, byte[] candata, int length, double phys)
        {
    
            status = Kvadblib.StoreSignalValuePhys(signal.sh, candata, candata.Length, phys);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }

        #endregion

        #region  Acquire physical quantities according to signals and original values 
        // transformation CAN Data to floating point physical values 
        public bool GetSignalValueFloat(SIGNALSTRUCT signal, byte[] candata, int length, out double value)
        {
    
            status = Kvadblib.GetSignalValueFloat(signal.sh, out value, candata, candata.Length);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }

        // transformation CAN Data to integer physical value 
        public bool GetSignalValueInteger(SIGNALSTRUCT signal, byte[] candata, int length, out int value)
        {
    
            status = Kvadblib.GetSignalValueInteger(signal.sh, out value, candata, candata.Length);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }

        //2 transformation CAN Data to enumerated physical values 
        public bool GetSignalValueEnum(SIGNALSTRUCT signal, byte[] candata, int length, out string value)
        {
    
            status = Kvadblib.GetSignalValueEnum(signal.sh, out value, candata, candata.Length);
            if (status != Kvadblib.Status.OK) return false;
            return true;
        }
        #endregion
    }
}

C:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h" 
#include "can.h" 
 
  


 int main(void)
 {
    	 
		u8 key;
	u8 i=0,t=0;
	u8 cnt=0;
	u8 canbuf[8];
	u8 res;
	u8 mode=CAN_Mode_LoopBack;//CAN Working mode ;CAN_Mode_Normal(0): Common mode ,CAN_Mode_LoopBack(1): Loopback mode 

	delay_init();	    	 // Delay function initialization  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// Set interrupt priority group to group 2:2 Bit preemption priority ,2 Bit response priority 
	uart_init(115200);	 	// The serial port is initialized to 115200
	LED_Init();		  		// Initialization and LED Connected hardware interface 
	LCD_Init();			   	// initialization LCD 
	KEY_Init();				// Key initialization  
   
	CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);//CAN Initialize loopback mode , Baud rate 500Kbps 

 	POINT_COLOR=RED;// Set the font to red  
	LCD_ShowString(60,50,200,16,16,"WarShip STM32");	
	LCD_ShowString(60,70,200,16,16,"CAN TEST");	
	LCD_ShowString(60,90,200,16,16,"[email protected]");
	LCD_ShowString(60,110,200,16,16,"2015/1/15");
	LCD_ShowString(60,130,200,16,16,"LoopBack Mode");	 
	LCD_ShowString(60,150,200,16,16,"KEY0:Send WK_UP:Mode");// Display prompt message  
	POINT_COLOR=BLUE;// Set the font to blue  
	LCD_ShowString(60,170,200,16,16,"Count:");			// Displays the current count value  
	LCD_ShowString(60,190,200,16,16,"Send Data:");		// Prompt to send data  
	LCD_ShowString(60,250,200,16,16,"Receive Data:");	// Prompt received data  
 	while(1)
	{
    
		key=KEY_Scan(0);
		if(key==KEY0_PRES)//KEY0 Press down , Send data once 
		{
    
			for(i=0;i<8;i++)
			{
    
				canbuf[i]=cnt+i;// Fill the send buffer 
				if(i<4)LCD_ShowxNum(60+i*32,210,canbuf[i],3,16,0X80);	// Display the data 
				else LCD_ShowxNum(60+(i-4)*32,230,canbuf[i],3,16,0X80);	// Display the data 
 			}
			res=Can_Send_Msg(canbuf,8);// send out 8 Bytes  
			if(res)LCD_ShowString(60+80,190,200,16,16,"Failed");		// Prompt send failed 
			else LCD_ShowString(60+80,190,200,16,16,"OK ");	 		// Prompt sent successfully  
		}else if(key==WKUP_PRES)//WK_UP Press down , change CAN Working mode of 
		{
    	   
			mode=!mode;
  			CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,mode);//CAN Normal mode initialization ,  Baud rate 500Kbps 
			POINT_COLOR=RED;// Set the font to red  
			if(mode==0)// Common mode , need 2 A development board 
			{
    
				LCD_ShowString(60,130,200,16,16,"Nnormal Mode ");	    
			}else // Loopback mode , A development board can be tested .
			{
    
 				LCD_ShowString(60,130,200,16,16,"LoopBack Mode");
			}
 			POINT_COLOR=BLUE;// Set the font to blue  
		}		 
		key=Can_Receive_Msg(canbuf);
		if(key)// Received data 
		{
    			
			LCD_Fill(60,270,130,310,WHITE);// Clear the previous display 
 			for(i=0;i<key;i++)
			{
    									    
				if(i<4)LCD_ShowxNum(60+i*32,270,canbuf[i],3,16,0X80);	// Display the data 
				else LCD_ShowxNum(60+(i-4)*32,290,canbuf[i],3,16,0X80);	// Display the data 
 			}
		}
		t++; 
		delay_ms(10);
		if(t==20)
		{
    
			LED0=!LED0;// Indicates that the system is running  
			t=0;
			cnt++;
			LCD_ShowxNum(60+48,170,cnt,3,16,0X80);	// Display the data 
		}		   
	}
}


=========C=

#ifndef __CAN_H
#define __CAN_H 
#include "sys.h" 

 
//CAN receive RX0 Interrupt enable 
#define CAN_RX0_INT_ENABLE 0 //0, Do not enable ;1, Can make . 
//tsjw: Resynchronize jump time units . Range :CAN_SJW_1tq~ CAN_SJW_4tq 
//tbs2: Period of time  2  Time unit .  Range :CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1: Period of time  1  Time unit .  Range :CAN_BS1_1tq ~CAN_BS1_16tq
//brp : Baud rate divider . Range :1~1024; tq=(brp)*tpclk1
// Baud rate =Fpclk1/((tbs1+1+tbs2+1+1)*brp);
//mode:CAN_Mode_Normal, Common mode ;CAN_Mode_LoopBack, Loopback mode ;

//Fpclk1  The clock is set to... During initialization  36M, If you set 
//CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);
// Then the baud rate is :36M/((8+9+1)*4)=500Kbps
// Return value :0, initialization  OK;
//  other , initialization failed ; u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode);//CAN initialization 

u8 Can_Send_Msg(u8* msg,u8 len);						// send data 

u8 Can_Receive_Msg(u8 *buf);							// receive data 
#endif
#include "can.h"
#include "led.h"
#include "delay.h"
#include "usart.h"
 
 
//CAN initialization 
//tsjw: Resynchronize jump time units . Range :CAN_SJW_1tq~ CAN_SJW_4tq
//tbs2: Period of time 2 Time unit .  Range :CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1: Period of time 1 Time unit .  Range :CAN_BS1_1tq ~CAN_BS1_16tq
//brp : Baud rate divider . Range :1~1024; tq=(brp)*tpclk1
// Baud rate =Fpclk1/((tbs1+1+tbs2+1+1)*brp);
//mode:CAN_Mode_Normal, Common mode ;CAN_Mode_LoopBack, Loopback mode ;
//Fpclk1 The clock is set to... During initialization 36M, If you set CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);
// Then the baud rate is :36M/((8+9+1)*4)=500Kbps
// Return value :0, initialization OK;
//  other , initialization failed ; 
u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
     
	GPIO_InitTypeDef 		GPIO_InitStructure; 
	CAN_InitTypeDef        	CAN_InitStructure;
	CAN_FilterInitTypeDef  	CAN_FilterInitStructure;
#if CAN_RX0_INT_ENABLE 
	NVIC_InitTypeDef  		NVIC_InitStructure;
#endif

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// Can make PORTA The clock  

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);// Can make CAN1 The clock  

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	// Reuse push pull 
	GPIO_Init(GPIOA, &GPIO_InitStructure);			// initialization IO

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	// Pull up input 
	GPIO_Init(GPIOA, &GPIO_InitStructure);			// initialization IO

	//CAN Unit setup 
	CAN_InitStructure.CAN_TTCM=DISABLE;			// Non time triggered communication mode  
	CAN_InitStructure.CAN_ABOM=DISABLE;			// Software automatic offline management  
	CAN_InitStructure.CAN_AWUM=DISABLE;			// Sleep mode wakes up through software ( eliminate CAN->MCR Of SLEEP position )
	CAN_InitStructure.CAN_NART=ENABLE;			// Automatic transmission of messages is prohibited  
	CAN_InitStructure.CAN_RFLM=DISABLE;		 	// Message not locked , The new covers the old  
	CAN_InitStructure.CAN_TXFP=DISABLE;			// The priority is determined by the message identifier  
	CAN_InitStructure.CAN_Mode= mode;	        // Mode setting : mode:0, Common mode ;1, Loopback mode ; 
	// set baud rate 
	CAN_InitStructure.CAN_SJW=tsjw;				// Resynchronize jump width (Tsjw) by tsjw+1 Time units  CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
	CAN_InitStructure.CAN_BS1=tbs1; 			//Tbs1=tbs1+1 Time units CAN_BS1_1tq ~CAN_BS1_16tq
	CAN_InitStructure.CAN_BS2=tbs2;				//Tbs2=tbs2+1 Time units CAN_BS2_1tq ~ CAN_BS2_8tq
	CAN_InitStructure.CAN_Prescaler=brp;        // Division coefficient (Fdiv) by brp+1 
	CAN_Init(CAN1, &CAN_InitStructure);        	// initialization CAN1 

	CAN_FilterInitStructure.CAN_FilterNumber=0;	// filter 0
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	// Mask bit mode 
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; 	//32 A wide  
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;	//32 position ID
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32 position MASK
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;// filter 0 Related to FIFO0
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// Activate the filter 0

	CAN_FilterInit(&CAN_FilterInitStructure);			// Filter initialization 
	
#if CAN_RX0_INT_ENABLE 
	CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);				//FIFO0 Message registration interruption allows . 

	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     //  The primary priority is 1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            //  Secondary priority is 0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
#endif
	return 0;
}   
 
#if CAN_RX0_INT_ENABLE // Can make RX0 interrupt 
// Interrupt service function  
void USB_LP_CAN1_RX0_IRQHandler(void)
{
    
  	CanRxMsg RxMessage;
	int i=0;
    CAN_Receive(CAN1, 0, &RxMessage);
	for(i=0;i<8;i++)
	printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data[i]);
}
#endif

//can Send a set of data ( Fixed format :ID by 0X12, Standard frame , Data frame ) 
//len: Data length ( The maximum is 8) 
//msg: Data pointer , The maximum is 8 Bytes .
// Return value :0, success ;
//  other , Failure ;
u8 Can_Send_Msg(u8* msg,u8 len)
{
    	
	u8 mbox;
	u16 i=0;
	CanTxMsg TxMessage;
	TxMessage.StdId=0x12;			//  Standard Identifier  
	TxMessage.ExtId=0x12;			//  Set identifier extension  
	TxMessage.IDE=CAN_Id_Standard; 	//  Standard frame 
	TxMessage.RTR=CAN_RTR_Data;		//  Data frame 
	TxMessage.DLC=len;				//  The length of data to be sent 
	for(i=0;i<len;i++)
	TxMessage.Data[i]=msg[i];			          
	mbox= CAN_Transmit(CAN1, &TxMessage);   
	i=0; 
	while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;	// Wait for the end of sending 
	if(i>=0XFFF)return 1;
	return 0;	 
}
//can Port to receive data query 
//buf: Data cache ; 
// Return value :0, No data received ;
//  other , Length of data received ;
u8 Can_Receive_Msg(u8 *buf)
{
    		   		   
 	u32 i;
	CanRxMsg RxMessage;
    if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0;		// No data received , immediate withdrawal  
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);// Reading data  
    for(i=0;i<8;i++)
    buf[i]=RxMessage.Data[i];  
	return RxMessage.DLC;	
}
typedef struct
{
    
  uint32_t StdId;  /*!< Specifies the standard identifier. This parameter can be a value between 0 to 0x7FF. */

  uint32_t ExtId;  /*!< Specifies the extended identifier. This parameter can be a value between 0 to 0x1FFFFFFF. */

  uint8_t IDE;     /*!< Specifies the type of identifier for the message that will be transmitted. This parameter can be a value of @ref CAN_identifier_type */

  uint8_t RTR;     /*!< Specifies the type of frame for the message that will be transmitted. This parameter can be a value of @ref CAN_remote_transmission_request */

  uint8_t DLC;     /*!< Specifies the length of the frame that will be transmitted. This parameter can be a value between 0 to 8 */

  uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0 to 0xFF. */
} CanTxMsg;

/** * @brief CAN Rx message structure definition */

typedef struct
{
    
  uint32_t StdId;  /*!< Specifies the standard identifier. This parameter can be a value between 0 to 0x7FF. */

  uint32_t ExtId;  /*!< Specifies the extended identifier. This parameter can be a value between 0 to 0x1FFFFFFF. */

  uint8_t IDE;     /*!< Specifies the type of identifier for the message that will be received. This parameter can be a value of @ref CAN_identifier_type */

  uint8_t RTR;     /*!< Specifies the type of frame for the received message. This parameter can be a value of @ref CAN_remote_transmission_request */

  uint8_t DLC;     /*!< Specifies the length of the frame that will be received. This parameter can be a value between 0 to 8 */

  uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to 0xFF. */

  uint8_t FMI;     /*!< Specifies the index of the filter the message stored in the mailbox passes through. This parameter can be a value between 0 to 0xFF */
} CanRxMsg;
原网站

版权声明
本文为[Rodinia lava]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206242001449204.html