打印
[其它应用]

单片机软件系统框架和多任务调度

[复制链接]
7451|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gwsan|  楼主 | 2021-6-5 21:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
这里我用的单片机算是中颖的sh79f9401芯片


使用特权

评论回复
沙发
gwsan|  楼主 | 2021-6-5 21:15 | 只看该作者
UART底层驱动相关函数:
       
                //UART相关寄存器初始化
                void Uart_Init(void)
                {
                        PCON = 0x00;//选择SSTAT0
                        SCON = 0x50;//01000000  方式一
                        SBRTL = (u8int)(_SBRT & 0xFF);
                        SBRTH= (u8int)((0x80)|((_SBRT >> 8) & 0xFF));
                        SFINE = _SFINE;
                        ES0 = 1;//允许EUART0中断
                }
               
                //UART中断服务程序
                void        EUART_0_ISP(void) interrupt 4
                {
                        if(TI)
                        {
                                TI = 0;
                                Drv_Uart_Tx_It_Handle(UART_PORT_0);
                        }
                        if(RI)
                        {
                                RI = 0;
                                Drv_Uart_Rx_It_Handle(UART_PORT_0,SBUF);
                        }
                }
               
                //UART发送一Byte数据
                void Drv_Hardware_uart_SendByte(UART_PORT_TYPE ePort,char Data)
                {
                        if(ePort == UART_PORT_0)
                        {
                                ACC = Data;
                                SBUF = ACC;载入要发送的数据       
                        }
                }


使用特权

评论回复
板凳
gwsan|  楼主 | 2021-6-5 21:16 | 只看该作者
中间层UART相关函数:
                #define _DRV_UART_C_
                #include "drv.h"
                #include "mw_uart.h"
               
                //这里是发送和接受数据的缓冲区
                u8int Uart_0_TxBuf[UART_0_TX_SIZE] = {0};//UART_0_TX_SIZE在uart.h头文件里根据需求和硬件资源自定义大小
                u8int Uart_0_RxBuf[UART_0_RX_SIZE] = {0};//UART_0_RX_SIZE在uart.h头文件里根据需求和硬件资源自定义大小
               
                //UART相关结构体
                typedef struct
                {
                        u8int * pu8TxAdd;//添加数据的地址,该地址数据无效
                        u8int * pu8TxValid;//有效数据的首
                        u8int * pu8TxMinAddr;//缓冲区最小地址
                        u8int * pu8TxMaxAddr;//缓冲区最大地址
                        u8int u8TxBufDataSize;//缓冲区已使用空间,有效数据大小
                        BOOL bTxIsStop;//中断是否在发送标记
               
                        u8int * pu8RxAdd;
                        u8int * pu8RxValid;
                        u8int * pu8RxMinAddr;
                        u8int * pu8RxMaxAddr;
                        u8int u8RxBufDataSize;
                }DRV_UART_INFO;
                DRV_UART_INFO sDrvUartInfo[1];
               


使用特权

评论回复
地板
gwsan|  楼主 | 2021-6-5 21:17 | 只看该作者
//初始化UART数据缓冲区
                void MW_Uart_Data_Init(void)
                {
                        sDrvUartInfo[UART_PORT_0].pu8TxAdd = &Uart_0_TxBuf[0];
                        sDrvUartInfo[UART_PORT_0].pu8TxValid = &Uart_0_TxBuf[0];
                        sDrvUartInfo[UART_PORT_0].pu8TxMinAddr = &Uart_0_TxBuf[0];
                        sDrvUartInfo[UART_PORT_0].pu8TxMaxAddr = &Uart_0_TxBuf[UART_0_TX_SIZE - 1];
                        sDrvUartInfo[UART_PORT_0].u8TxBufDataSize = 0;
                        sDrvUartInfo[UART_PORT_0].bTxIsStop = TRUE;
                        sDrvUartInfo[UART_PORT_0].pu8RxAdd = &Uart_0_RxBuf[0];
                        sDrvUartInfo[UART_PORT_0].pu8RxValid = &Uart_0_RxBuf[0];
                        sDrvUartInfo[UART_PORT_0].pu8RxMinAddr = &Uart_0_RxBuf[0];
                        sDrvUartInfo[UART_PORT_0].pu8RxMaxAddr = &Uart_0_RxBuf[UART_0_RX_SIZE - 1];
                        sDrvUartInfo[UART_PORT_0].u8RxBufDataSize = 0;
                }


使用特权

评论回复
5
gwsan|  楼主 | 2021-6-5 21:19 | 只看该作者
//将需要发送的数据添加到待发送的数据缓冲区,所有数据实际上是再终端里面发送
                void MW_Uart_Send_Data_Add(UART_PORT_TYPE ePort,u8int * buf,u16int Size)
                {
                        u8int Len = 0;
                        //if((UART_0_TX_SIZE - sDrvUartInfo[ePort].u8TxBufDataSize) >= Size)
                        {剩余空间比要发送的数据大才会发送,否则丢弃要发送的数据
                                sDrvUartInfo[ePort].u8TxBufDataSize = sDrvUartInfo[ePort].u8TxBufDataSize + Size;更新剩余空间大小
                                while(Len < Size)
                                {
                                        *sDrvUartInfo[ePort].pu8TxAdd = buf[Len];
                                        if(sDrvUartInfo[ePort].pu8TxAdd < sDrvUartInfo[ePort].pu8TxMaxAddr)
                                        {
                                                sDrvUartInfo[ePort].pu8TxAdd ++;
                                        }
                                        else
                                        {
                                                sDrvUartInfo[ePort].pu8TxAdd = sDrvUartInfo[ePort].pu8TxMinAddr;
                                        }
                                        Len ++;
                                }
                                if(sDrvUartInfo[ePort].bTxIsStop)
                                {
                                        sDrvUartInfo[ePort].bTxIsStop = FALSE;
                                        Drv_Hardware_uart_SendByte(ePort,*sDrvUartInfo[ePort].pu8TxValid);
                                }
                        }
                }


使用特权

评论回复
6
gwsan|  楼主 | 2021-6-5 21:20 | 只看该作者
//这个是中断发送函数
                void MW_Uart_Tx_It_Handle(UART_PORT_TYPE ePort)
                {       
                        对上次中断进行指针移动同时更新剩余空间大小
                        sDrvUartInfo[ePort].u8TxBufDataSize --;
                        if(sDrvUartInfo[ePort].pu8TxValid < sDrvUartInfo[ePort].pu8TxMaxAddr)
                        {
                                sDrvUartInfo[ePort].pu8TxValid ++;
                        }
                        else
                        {
                                sDrvUartInfo[ePort].pu8TxValid = sDrvUartInfo[ePort].pu8TxMinAddr;
                        }
                       
                        如果发送剩余空间小于缓冲区大小说明还有数据等待发送
                        if(sDrvUartInfo[ePort].u8TxBufDataSize > 0)
                        {
                                Drv_Hardware_uart_SendByte(ePort,*sDrvUartInfo[ePort].pu8TxValid);
                        }
                        else
                        {
                                sDrvUartInfo[ePort].bTxIsStop = TRUE;
                        }
                }


使用特权

评论回复
7
gwsan|  楼主 | 2021-6-5 21:21 | 只看该作者
//这个是中断接收函数
                void MW_Uart_Rx_It_Handle(UART_PORT_TYPE ePort,u8int Data)
                {
                        //if(sDrvUartInfo[ePort].u8RxBufDataSize < UART_0_RX_SIZE)缓冲区空间没满,填数据,否则丢弃数据
                        {
                                直接往缓冲里填接收到的数据
                                *sDrvUartInfo[ePort].pu8RxAdd = Data;
                                sDrvUartInfo[ePort].u8RxBufDataSize ++;
                                if(sDrvUartInfo[ePort].pu8RxAdd == sDrvUartInfo[ePort].pu8RxMaxAddr)
                                {
                                        sDrvUartInfo[ePort].pu8RxAdd = sDrvUartInfo[ePort].pu8RxMinAddr;
                                }
                                else
                                {
                                        sDrvUartInfo[ePort].pu8RxAdd ++;
                                }
                        }
                }


使用特权

评论回复
8
gwsan|  楼主 | 2021-6-5 21:21 | 只看该作者
//用户获取从串口接收到的数据
                void MW_Uart_Get_Rx_Data(UART_PORT_TYPE ePort,UART_UserDataType *psData)
                {
                        u16int u16Count = 0;
                        u8int* pu8UserBuf;
                        u8int *pu8GetData;
                        pu8UserBuf = &psData->u8UserData[0];
                        pu8GetData = sDrvUartInfo[ePort].pu8RxValid;
                        while(u16Count < sDrvUartInfo[ePort].u8RxBufDataSize)复制所有数据
                        {
                                *pu8UserBuf = *pu8GetData;
                                if(pu8GetData == sDrvUartInfo[ePort].pu8RxMaxAddr)
                                {
                                        pu8GetData = sDrvUartInfo[ePort].pu8RxMinAddr;
                                }
                                else
                                {
                                        pu8GetData++;
                                }
                                pu8UserBuf++;
                                u16Count ++;
                        }
                        psData->u16Size = sDrvUartInfo[ePort].u8RxBufDataSize;
                }


使用特权

评论回复
9
gwsan|  楼主 | 2021-6-5 21:22 | 只看该作者
//用户获取从串口接收到的数据后应当释放相应大小的缓冲区数据
                void MW_Uart_Free_Rx_Buffer(UART_PORT_TYPE ePort, u8int u8Len)
                {
                        while (u8Len --)
                        {
                                if (sDrvUartInfo[ePort].pu8RxValid == sDrvUartInfo[ePort].pu8RxMaxAddr)
                                {
                                        sDrvUartInfo[ePort].pu8RxValid = sDrvUartInfo[ePort].pu8RxMinAddr;
                                }
                                else
                                {
                                        sDrvUartInfo[ePort].pu8RxValid ++;
                                }
                                sDrvUartInfo[ePort].u8RxBufDataSize --;
                        }
                }


使用特权

评论回复
10
两只袜子| | 2021-6-9 16:37 | 只看该作者
很不错的帖子,支持下

使用特权

评论回复
11
xxx715| | 2021-8-30 12:05 | 只看该作者
谢谢分享,支持共享!

使用特权

评论回复
12
七毛钱| | 2021-9-1 16:33 | 只看该作者
很不错的,支持一下

使用特权

评论回复
13
armcortex| | 2023-1-8 20:33 | 只看该作者
感谢楼主的讲解

使用特权

评论回复
14
vivilyly| | 2023-2-2 09:57 | 只看该作者
单片机如何实现多任务               

使用特权

评论回复
15
sdCAD| | 2023-2-2 11:40 | 只看该作者
单片机 怎么替换pc指针值              

使用特权

评论回复
16
cashrwood| | 2023-2-2 13:56 | 只看该作者
单片机能同时执行多少个任务?               

使用特权

评论回复
17
wujiawen8000| | 2023-2-2 14:15 | 只看该作者
大神

使用特权

评论回复
18
bestwell| | 2023-2-2 15:42 | 只看该作者
通过实现中断来完成任务之间的切换么?

使用特权

评论回复
19
elsaflower| | 2023-2-4 14:44 | 只看该作者
那个如何实现单片机多个函数同时运行?

使用特权

评论回复
20
10299823| | 2023-2-4 15:23 | 只看该作者
单片机中如何实现多线程,多任务?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

3427

帖子

1

粉丝