这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【STCAi8051U】Ai8051U的硬件乘除例程

共1条 1/1 1 跳转至

【STCAi8051U】Ai8051U的硬件乘除例程

专家
2025-12-17 16:41:33     打赏

使用Ai8051U的32位硬件乘除单元,可以选择在Keil项目中加入库文件“Ai8051U_32_MDU32_V1.0.LIB”。如下图所示,将库文件追加到工程中。

这里我依旧使用擎天柱开发板做测试,程序代码:


//测试工作频率为 11.0592MHz
// 本例测试使用MDU计算32位的乘除法计算
// 测试使用Timer2作为串口1的波特率发生器
// 串口1:P3.6(RXD),P3.7(TXD)


#include "Ai8051U.H" 
#include "intrins.h"
#include "stdio.h"

typedef unsigned char   u8;     //  8 bits 
typedef unsigned int    u16;    // 16 bits 
typedef unsigned long   u32;    // 32 bits 


sbit TPIN  =  P1^0;


volatile unsigned long near uval1, uval2;
volatile unsigned long int near uval;

volatile long int lval1, lval2;
volatile long int lval;


#define FOSC 11059200UL //定义为无符号长整型,避免计算溢出
#define BRT (65536 - (FOSC / 115200+2) / 4)   //加 2 操作是为了让 Keil 编译器,自动实现四舍五入运算
bit busy1;
char wptr1;
char rptr1;
char buffer1[64];

// 初始化定时器2
void Timer2Init(void) {
    T2L = BRT;
    T2H = BRT >> 8;
    S1BRT = 1;  // S1BRT:串口 1 波特率发生器选择位, 0:选择定时器 1 作为波特率发生器, 1:选择定时器 2 作为波特率发生器(默认值)
    T2x12 = 1;
    T2R = 1;    
}

// 串口1
//---------------------------------------------------------------
// 串口1的中断处理
void Uart1Isr() interrupt 4 {
    if (TI) {
        TI = 0;
        busy1 = 0;
    }
    if (RI) {
        RI = 0;
        buffer1[wptr1++] = SBUF;
        wptr1 &= 0x0f;
    }
}

// 初始化串口1
void Uart1Init() {
    SCON = 0x50;  //
    wptr1 = 0x00;
    rptr1 = 0x00;
    busy1 = 0;
    
    P_SW1 |= 0x40;   // 选择P3.6,P3.7,因为擎天柱开发板上不提供P3.0,P3.1引脚
}

// 向串口1输出一个字符
void Uart1Send(char dat) {
    while (busy1);
    busy1 = 1;
    SBUF = dat;
}

// 向串口1输出一个字符串
void Uart1SendStr(char *p) {
    while (*p) {
        Uart1Send(*p++);
    }
}

// 延时
void delay_ms(u16 ms) {
    u16 i;
    do {
        i = FOSC/3000;
        while(--i);
    } while(--ms);
}


void toggle(void) {
    if (TPIN == 0) {
        TPIN = 1;
    } else {
        TPIN = 0;
    
    }
}

void main() {
    unsigned int val = 0;               // ADC转换值
    float v1=0.0;                // 电压值
    unsigned char str[128]={0};
    
    EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
    //(32 位模式请使用这句,注释下一句)
    // P_SW2 |= 0x80; //允许访问扩展的特殊寄存器,XFR
    //(8 位模式请使用这句,注释上一句)
    WTST = 0; //设置取程序代码等待时间,
    //赋值为 0 表示不等待,程序以最快速度运行
    CKCON = 0; //设置访问片内的 xdata 速度,
    
    //赋值为 0 表示用最快速度访问,不增加额外的等待时间
    P0M0 = 0x00;    P0M1 = 0x00;
    P1M0 = 0x00;    P1M1 = 0x00;
    P2M0 = 0x00;    P2M1 = 0x00;
    P3M0 = 0x00;    P3M1 = 0x00;
    P4M0 = 0x00;    P4M1 = 0x00;
    P5M0 = 0x00;    P5M1 = 0x00;
    
    Timer2Init();
    
    Uart1Init();
    
    delay_ms(10);
    
    ES = 1;
   
    EA = 1;
    
    Uart1SendStr("AI8051U MDU32 Test.\r\n");
    
    TPIN = 0;  // 计算开始信号
    delay_ms(20);
    
    while (1) {
        // 无符号数除法
        toggle();
        Uart1SendStr("Chufa    of ulong\r\n");
        uval1 =  99999999;
        uval2 =  9999;
        uval = uval1 / uval2;
        sprintf(str, "%lld\r\n",uval);
        Uart1SendStr(str);  
        
        
        // 有符号数除法
        toggle();
        Uart1SendStr("Chufa    of ulong\r\n");
        lval1 = 99999999;
        lval2 = -9999;
        lval = lval1 / lval2;
        sprintf(str, "%lld\r\n",lval);
        Uart1SendStr(str);
        

        // 无符号数乘法
        toggle();
        Uart1SendStr("Chengfa  of ulong\r\n");
        uval1 =  9999;
        uval2 =  9999;
        uval = uval1 * uval2;
        sprintf(str, "%lld\r\n",uval);
        Uart1SendStr(str);        

        // 有符号数乘法
        toggle();
        Uart1SendStr("Chengfa  of  long\r\n");
        lval1 = 9999;
        lval2 = -9999;
        lval = lval1 * lval2;
        sprintf(str, "%lld\r\n",lval);
        Uart1SendStr(str);

    }
}

程序里加了一个TPIN的指示信号,是为了以后对比不使用MDU乘除法单元时,做时序对比,也就是所花时间的对比。

测试结果:

图片7.png










关键词: 懒猫的学习笔记     Ai8051U     硬件乘除法例程    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]