打印

伪本征函数——Keil C51头文件INTRINS.H的扩容工程(第四版)

[复制链接]
3929|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hotpower|  楼主 | 2009-1-16 21:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*--------------------------------------------------------------------------
  伪本征函数——Keil C51头文件INTRINS.H的扩容工程(第四版)
根据HotPower的“同名小说《Keil C51红杏出墙记》”改编
最初建立时间: 2003.03.08 
最近修改时间: 2008.11.19
修 改 原  因: 支持Keil C51工程多文件系统,避免重复定义汇编数组问题.
应        用: _reset_();//软件复位
              _start_();//启动时执行2次RETI
unsigned char SPIReadWrite(unsigned char val)
{
unsigned char i;
 ACC = val;//取发送数据
 for (i = 8; i > 0; i --)
 {
  CY = SPISIO;//读1位数据
  _rlca_();//左移1位数据
  SPICLK = 1;//拉高时钟
  SPISIO = CY;//发送数据
  SPICLK = 0;拉低时钟
 }
 SPISIO = 1;//释放数据总线
 return ACC;
}
说        明: 一般宏不需添加HotIns.C,只需HotIns.H文件即可.
              涉及汇编数组的宏如_start_()需要再添加HotIns.C文件.
菜农HotPower@126.com 2008.11.19 于西安大雁塔村大队部
--------------------------------------------------------------------------*/




相关链接:https://bbs.21ic.com/upfiles/img/20091/2009116212320410.rar

相关帖子

沙发
ljm810010| | 2009-1-16 22:25 | 只看该作者

什么东西,菜农大叔怎么不详细点说说?

使用特权

评论回复
板凳
hotpower|  楼主 | 2009-1-16 22:27 | 只看该作者

最近受批判~~~低调点~~~

使用特权

评论回复
地板
ljm810010| | 2009-1-16 22:37 | 只看该作者

哪里?有这回事?技术多样性,没什么批判不批判的

使用特权

评论回复
5
airwill| | 2009-1-18 00:35 | 只看该作者

还以为

    hot兄不研究 51 了, 看了近年来的好多大作.
技术提升,无止境!

使用特权

评论回复
6
古道热肠| | 2009-1-18 09:45 | 只看该作者

哈哈,这个函数在代码尺寸和速度上找到了平衡,论效率,看老

//--------------------------------XWJ版------------------------------------
#define _rrca_() CY = ACC & 0x01
#define _rlca_() CY = ACC & 0x80
uint8 SD_SPI_ReadByte(void)
{
//初始化SI引脚状态
    Macro_Set_SI_High();

//Bit7 Shift Out
    Macro_Set_CLK_Low();
    Macro_Set_CLK_High();
    CY = c_SPI_SO;    
    _rlca_();

//Bit6 Shift Out
    Macro_Set_CLK_Low();
    Macro_Set_CLK_High();
    CY = c_SPI_SO;    
    _rlca_();

//Bit5 Shift Out
    Macro_Set_CLK_Low();
    Macro_Set_CLK_High();
    CY = c_SPI_SO;    
    _rlca_();

//Bit4 Shift Out
    Macro_Set_CLK_Low();
    Macro_Set_CLK_High();
    CY = c_SPI_SO;    
    _rlca_();

//Bit3 Shift Out
    Macro_Set_CLK_Low();
    Macro_Set_CLK_High();
    CY = c_SPI_SO;    
    _rlca_();

//Bit2 Shift Out
    Macro_Set_CLK_Low();
    Macro_Set_CLK_High();
    CY = c_SPI_SO;    
    _rlca_();

//Bit1 Shift Out
    Macro_Set_CLK_Low();
    Macro_Set_CLK_High();
    CY = c_SPI_SO;    
    _rlca_();

//Bit0 Shift Out
    Macro_Set_CLK_Low();
    Macro_Set_CLK_High();
    CY = c_SPI_SO;    
    _rlca_();

    return(ACC);
}
//-------------------------------------------------------------------

//-------------------------------------------------------

sbit ACC0 = ACC^0;
sbit ACC1 = ACC^1;
sbit ACC2 = ACC^2;
sbit ACC3 = ACC^3;
sbit ACC4 = ACC^4;
sbit ACC5 = ACC^5;
sbit ACC6 = ACC^6;
sbit ACC7 = ACC^7;

void SD_SPI_WriteByte(uint8 ucSendData)  
{   
    ACC = ucSendData;
    
//Bit7 Shift Out To SD Card
    Macro_Set_CLK_Low();
//    c_SPI_SI = WriteData_Bit7;
    c_SPI_SI = ACC7;
//    c_SPI_SI = CY;

    Macro_Set_CLK_High();

//Bit6 Shift Out To SD Card
    Macro_Set_CLK_Low();
//    c_SPI_SI = WriteData_Bit6;
    c_SPI_SI = ACC6;

    Macro_Set_CLK_High();
//Bit5 Shift Out To SD Card
    Macro_Set_CLK_Low();
//    c_SPI_SI = WriteData_Bit5;
    c_SPI_SI = ACC5;

    Macro_Set_CLK_High();
//Bit4 Shift Out To SD Card
    Macro_Set_CLK_Low();
//    c_SPI_SI = WriteData_Bit4;
    c_SPI_SI = ACC4;

    Macro_Set_CLK_High();
//Bit3 Shift Out To SD Card
    Macro_Set_CLK_Low();
//    c_SPI_SI = WriteData_Bit3;
    c_SPI_SI = ACC3;

    Macro_Set_CLK_High();
//Bit2 Shift Out To SD Card
    Macro_Set_CLK_Low();
//    c_SPI_SI = WriteData_Bit2;
    c_SPI_SI = ACC2;

    Macro_Set_CLK_High();
//Bit1 Shift Out To SD Card
    Macro_Set_CLK_Low();
//    c_SPI_SI = WriteData_Bit1;
    c_SPI_SI = ACC1;

    Macro_Set_CLK_High();
//Bit0 Shift Out To SD Card
    Macro_Set_CLK_Low();
//    c_SPI_SI = WriteData_Bit0;
    c_SPI_SI = ACC0;

    Macro_Set_CLK_High();


使用特权

评论回复
7
古道热肠| | 2009-1-18 09:46 | 只看该作者

谢谢共享!

老Hot的奉献精神值得学习!

使用特权

评论回复
8
hotpower|  楼主 | 2009-1-18 10:41 | 只看该作者

被逼无奈,A改C后代码减半,寄存器看不见

接手新工作后,看到老A和小A的程序----真倒塌~~~

无奈领导要俺添加新功能,只有看天书了。。。

A人的非结构化设计真是天马行空~~~看的呕吐!!!

A人真没局部变量的思路,全是全局变量!!!

整个51的寄存器都分配完了!!!

真不敢贴出他们的代码~~~那还叫“程序”???

漫天的喂狗,主程序走但定时器被关断,真正的程序功能无法实现。。。

问题太多~~~

俺的“狗论”是一处喂狗,比他们的“漫天的喂狗”要强百倍~~~

无奈用C改之,原程序约6K,现不到3K,全部变量只有几个。。。

因为程序功能是顺序执行的,占用寄存器数=全局变量数+函数最大局部寄存器数

所以,寄存器几乎“看不见”~~~

一句话---虽说俺也是A人,但俺还是个C人,至少是个AC人~~~


相关链接:http://blog.**/hotpower/194104/message.aspx

使用特权

评论回复
9
computer00| | 2009-1-18 10:49 | 只看该作者

俺是CA人~~~~C里面还是不要用ACC吧...

keil里要用位变量,可以直接声明一个全局位变量,然后来操作,不要用ACC为好。

使用特权

评论回复
10
hotpower|  楼主 | 2009-1-18 11:00 | 只看该作者

谈5楼代码的速度和效率

首先俺的是收发一体化。

差距在:
mov a,r7
mov r7,#8;多1条指令,执行1次
loop:
mov c,sio;读1条指令(write时多余,执行8次)
rlc a;执行8次
mov sio,c;写1条指令(read时多余,执行8次)
;.....

;......
djnz r7,loop;//多1条指令,执行8次

故差距是多执行1+8+8+8条指令,但是代码程序几乎是1:14左右

但是C人绝不取后者,大多为读写分离。

像读SD卡需要速度极限是才考虑后者。这可能是A人的考虑~~~

使用特权

评论回复
11
古道热肠| | 2009-1-18 12:01 | 只看该作者

贴个MP3播放功能的函数,最高速度大概在160Kbps,请大家提建议

sbit LED3Pin = P0^4;

void PlayMP3(unsigned char *SongName)
{
    int i =0,m =0;
//     static uint16 pointer=0;
    uchar *PDataBuffPoint;        //数据缓冲区指针.
    bool bFileEndFlag;            //读数据进行到文件结尾标志
    uchar ucOldKeyValue;

//    uchar p;
    uchar ucFileExtNameString[4];        
    uchar xdata ucDispBuff[20];

        memset(ucFileExtNameString,0x0,4);
        memcpy(ucFileExtNameString,SongName+8,3);
        ComShowString(c_COM1,"Current Play File ExtName is:");
        ComShowString(c_COM1,ucFileExtNameString);
                
        sprintf(ucDispBuff,"Music Mode:%s",ucFileExtNameString);
//        LCD_ShowString(3,0,"Mode:");
        LCD_ShowString(3,0,ucDispBuff);
        bFileEndFlag = false;
        
        while (!bFileEndFlag)
        {   
//            ComShowString(c_COM1,"Start Read Mp3 File Sector");
             RDCOUNT = ReadSector(SongName, Sector_Buf); 
            if(RDCOUNT <512)
            {
                bFileEndFlag = true;
            }

//            EA =1;
//            ComShowString(c_COM1,"Read Data Length is:");
//            ComSendText(c_COM1,&RDCOUNT,2);
            LED3Pin = ~LED3Pin;        //指示灯闪烁
//            ComSendText(c_COM1,Sector_Buf,512);
//            pointer=0;
            PDataBuffPoint = Sector_Buf;

            while(PDataBuffPoint < Sector_Buf+512)
            {
                        
                if(CheckVS1003B_DRQ())
                {
                    Mp3SelectData();

                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
    
                     VS1003B_WriteDAT(*PDataBuffPoint++);
                     VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
    
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
    
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);
                    VS1003B_WriteDAT(*PDataBuffPoint++);

                    Mp3DeselectData();
                }
                else
                {
                    if(!GetIR_Remote_Status())        //检测到红外线遥控信号的起始位
                    {
            
                        IRProcess();
                        ucOldKeyValue = c_Key_NoUse;
                    }

                    if(KbHit())        //
                    {
                        uchar ucKeyValue;
                        
                        ucKeyValue = KbGet();
                        
                        if(ucKeyValue != ucOldKeyValue)    //有新的按键时启动定时器
                        {    
                            TH0 = 0;
                            TL0 = 0;

                            TR0 = 1;
                            
                            ucOldKeyValue = ucKeyValue;
                            
                            KbProcess(ucKeyValue);        //按键处理
                        }
                        else
                        {
                            if(TF0)        //延时时间到
                            {    //重新启动定时器
                                TH0 = 0;
                                TL0 = 0;
                                TR0 = 1;
                                TF0=0;
                                KbProcess(ucKeyValue);        //按键处理
                            }
                        }
                    }
                }
            }
//--------------------------------插入按键处理-----------------------
#if 0
            if(KbHit())
            {
                if(KbHit())        //双保险,2级防抖
                {
                    uchar ucKeyValue;
                    
                    ucKeyValue = KbGet();
                    KbProcess(ucKeyValue);        //按键处理
                }
//                while(KbHit());        //等待按键释放
            }
#endif
//--------------------------------按键处理结束---------------------------------
            if (RDCOUNT < 512) 
            {
                //读取到最后一包数据的处理
                //判定当前播放的歌曲是否为Midi
                if(strcmp(ucFileExtNameString,"MID") == 0)
                {
                    ComShowString(c_COM1,"Midi File End Process");
                    VS1003B_Fill2048Zero();
                }

                NowPlaying++;            //指向下一曲。
                MP3InitFlag = 1;

                return;
            }

            if (ChangeSong) 
            { 
                DataRead = 0;
                ChangeSong = 0;
                //判定当前播放的歌曲是否为Midi
                if(strcmp(ucFileExtNameString,"MID") == 0)
                {
                    ComShowString(c_COM1,"Midi File End Process");
                    VS1003B_Fill2048Zero();
                }

                return;
            }
        }
    
}



使用特权

评论回复
12
hotpower|  楼主 | 2009-1-18 18:59 | 只看该作者

应该采用缓存(预处理)的思路~~~

在MP3模块VS1003B取播放语音数据时,语音数据应该早已存放在缓存中。
缓存一般为Flash扇区的1倍。

假若Flash扇区大小为512KByte,那么缓存大小应该为2个512KByte,
即2块512KByte.

当(前台)播放上块时,后台从flash中取出512KByte到下块。
当(前台)播放下块时,后台从flash中取出512KByte到上块。

此法比队列要快多了~~~

使用特权

评论回复
13
古道热肠| | 2009-1-19 12:23 | 只看该作者

哈哈,Hotpower这个思路好,但51单片机无能为力

51单片机总768字节的XDATA,而且也没有硬件支持后台的类DMA数据传送操作.
如果用AT91SAM7S64能实现这功能.PDC是自动读写数据到内存.

测试过程中,当MP3数据流为160Kbps时,单片机每次执行(CheckVS1003B_DRQ())都为真,已无暇顾及检测键盘输入了.

要想再提速,俺只想到两种硬件方式,1.用硬件SPI发数据,2.用51单片机UART工作在方式0,类SPI模式发送据.

使用特权

评论回复
14
hotpower|  楼主 | 2009-1-20 19:41 | 只看该作者

哈哈,这是俺在4Mbps时采用的策略~~~不过是在DSP上~~~

硬件SPI肯定要好些~~~

使用特权

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

本版积分规则

1460

主题

21619

帖子

506

粉丝