This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR5994:在 MSP430FR5994上运行的代码比在 MSP430F5529上运行的代码慢10倍以上

Guru**** 2584465 points
Other Parts Discussed in Thread: MSP430F5529, MSP430FR5994

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/610703/msp430fr5994-the-same-code-running-more-than-10x-slower-on-msp430fr5994-than-on-msp430f5529

器件型号:MSP430FR5994
主题中讨论的其他器件:MSP430F5529

大家好、

在这里、我遇到了 MSP430FR5994上的代码运行速度比 MSP430F5529慢的问题。

该代码用于 Pervasive EPD 显示、而 MSP430F5529的 Pervasive 提供了该代码。

唯一的区别在于 SPI 模块的代码。 MPS430FR5994使用 EUSCI、MSP430F5529使用 USCI 模块进行 SPI 通信。 已进行适当调整。 两个模块的转换速度相同、为13.5MHz (在示波器上测量)。

工作频率大致相同。 MSP430FR5994 = 24MHz、MSP430F5529 = 25MHz。

为 MSP430FR5994设置 FRAM 等待周期。

函数 stage_handle_Base (uint8_t * image_prt、long image_data_address、uint8_t stage_no、uint8_t lineoffset)、在 MSP430FR5994上执行时需要更多时间。 可能比 MSP430F5529慢10倍以上。 我发现、只要有一些存储器访问、问题就在内部环路中。

在 main 中、除了设置显示所需执行的其他操作外、还调用函数 void display_from _array_prt (uint8_t * previous_image_ptr、uint8_t * new_image_ptr)。

我找不到这样的原因、可能是因为 FRAM 的工作频率为8MHz、读取周期比闪存或 SRAM 的速度慢得多。

我非常感谢为加快 MSP430FR5994上的执行速度而提供的所有帮助。

谢谢你。

#define ADDRESS_NULL       0xFFFF
//EPD 面板参数
const struct COG_parameters_t COG_parameters[count_for_EPD_type] ={
   {
       //表示1.44”
       {0x00、0x00、0x00、0x00、0x00、0x0F、0xFF、0x00}、
       0x03、
       (128/8)、
       96、
       ((((((((128+96)*2)/8)+1),
       0、
       480
   }、
   {
       //对于2.0"
       {0x00、0x00、0x00、0x00、0x01、0xFF、0xE0、0x00}、
       0x03、
       (200/8)、
       96、
       (((((200+96)*2)/8)+1),
       0、
       480
   }、
   {
       //对于2.7"
       {0x00、0x00、0x00、0x7F、0xFF、0xFE、0x00、0x00}、
       0x00、
       (264/8)、
       176、
       ((((((((264+176)*2)/8)+1),
       0、
       630
   }
};
/*\简要 介绍室温下 Aurora Ma 的 EPD 波形参数
 *\请注意、以下波形表的参数与 G2 COG 文档不同、原因是
 *      不同 MCU 的块大小比精确的块时间更容易实现。
 *      这种方法也起作用。 *
const EPD_Aurora MA_RoomTemp_WaveformTable_StructE_ROOM_Waveform[COUNT_FOR_EPD_TYPE][3] ={
   {//对于1.44”
       {//50>=T¡Ö 40
           4、             //stage1_frame1
           16、            //stage1_block1
           2、             //stage1_step1
           155、           //stage2_t1
           155、           //stage2_t2
           4、             //stage2_cycle
           4、             //stage3_frame3
           16、            //stage3_Block3
           2              //stage3_step3
       }
       {//40>=T¡Ö 10
           4、             //stage1_frame1
           16、            //stage1_block1
           2、             //stage1_step1
           155、           //stage2_t1
           155、           //stage2_t2
           4、             //stage2_cycle
           4、             //stage3_frame3
           16、            //stage3_Block3
           2              //stage3_step3
       }
       ,{//10>=T¡Ö 0
           4、             //stage1_frame1
           16、            //stage1_block1
           2、             //stage1_step1
           155、           //stage2_t1
           155、           //stage2_t2
           4、             //stage2_cycle
           4、             //stage3_frame3
           16、            //stage3_Block3
           2              //stage3_step3
       }
   }、
   {//对于2.0"
       {//50>=T¡Ö 40
           4、             //stage1_frame1
           48、            //stage1_block1
           2、             //stage1_step1
           155、           //stage2_t1
           155、           //stage2_t2
           4、             //stage2_cycle
           4、             //stage3_frame3
           48、            //stage3_Block3
           2              //stage3_step3
       }、
       {//40>=T¡Ö 10
           2、             //stage1_frame1
           32、            //stage1_block1
           2、             //stage1_step1
           155、           //stage2_t1
           155、           //stage2_t2
           4、             //stage2_cycle
           2、             //stage3_frame3
           32、            //stage3_Block3
           2              //stage3_step3
       }、
       {//10>=T¡Ö 0
           3、             //stage1_frame1
           48、            //stage1_block1
           2、             //stage1_step1
           310、           //stage2_t1.
           310、           //stage2_t2
           4、             //stage2_cycle
           3、             //stage3_frame3
           48、            //stage3_Block3
           2              //stage3_step3
       }
   }、
   {//适用于2.7"
       {//50>=T¡Ö 40
           4、             //stage1_frame1
           4、             //stage1_block1
           2、             //stage1_step1
           155、           //stage2_t1
           155、           //stage2_t2
           4、             //stage2_cycle
           4、             //stage3_frame3
           22、            //stage3_Block3
           2              //stage3_step3
       }
       {//40>=T¡Ö 10
           2、             //stage1_frame1
           48、            //stage1_block1
           2、             //stage1_step1
           155、           //stage2_t1
           155、           //stage2_t2
           4、             //stage2_cycle
           2、             //stage3_frame3
           48、            //stage3_Block3
           2              //stage3_step3
       }
       ,{//10>=T¡Ö 0
           3、             //stage1_frame1
           16、            //stage1_block1
           2、             //stage1_step1
           310、           //stage2_t1.
           310、           //stage2_t2
           4、             //stage2_cycle
           3、             //stage3_frame3
           16、            //stage3_Block3
           2              //stage3_step3
       }
   }
};

/**
 *\简要 说明低温(低于零°C)下 Aurora Ma 的参数
 *\注意以下参数尚未确定。 有关详情、请联系无所不在的显示屏。
 *
const EPD_Aurora MA_LowTemp_WaveformTable_StructEPD_LOW_WaveformTable[COUNT_FOR_EPD_TYPE][5] ={
   {//对于2.0"
       {//0>=T¡Ö-5
           560、           //stage1_FrameTime
           5、             //stage1_Cycle
           560、           //stage2_FrameTime
           840、           //stage3_FrameTime
           8、             //stage3_Cycle
           560//stage4_FrameTime             
       }、
       {//-5>=T¡Ö-10
           560、           //stage1_FrameTime
           10、            //stage1_Cycle
           560、           //stage2_FrameTime
           840、           //stage3_FrameTime
           10、            //stage3_Cycle
           560//stage4_FrameTim             
       }、
       {//-10>=T¡Ö-15
           560、           //stage1_FrameTime
           15、            //stage1_Cycle
           1400、          //stage2_FrameTime
           1120、          //stage3_FrameTime
           8、             //stage3_Cycle
           1400           //stage4_FrameTim
       }、
       {//-15>=T¡Ö-20
           560、           //stage1_FrameTime
           20、            //stage1_Cycle
           1960、          //stage2_FrameTime
           1120、          //stage3_FrameTime
           8、             //stage3_Cycle
           1960           年//stage4_FrameTim
       }、
       {//-20>=T
           560、           //stage1_FrameTime
           25、            //stage1_Cycle
           1960、          //stage2_FrameTime
           1120、          //stage3_FrameTime
           8、             //stage3_Cycle
           1960           年//stage4_FrameTim
       }
   }、
   {//适用于2.7"
       {//0>=T¡Ö-5
           760、           //stage1_FrameTime
           5、             //stage1_Cycle
           760、           //stage2_FrameTime
           1520、          //stage3_FrameTime
           8、             //stage3_Cycle
           760//stage4_FrameTime             
       }、
       {//-5>=T¡Ö-10
           760、           //stage1_FrameTime
           10、            //stage1_Cycle
           760、           //stage2_FrameTime
           1520、          //stage3_FrameTime
           10、            //stage3_Cycle
           760//stage4_FrameTime             
       }、
       {//-10>=T¡Ö-15
           760、           //stage1_FrameTime
           15、            //stage1_Cycle
           1140、          //stage2_FrameTime
           1520、          //stage3_FrameTime
           12、            //stage3_Cycle
           1140           //stage4_FrameTime
       }、
       {//-15>=T¡Ö-20
           760、           //stage1_FrameTime
           20、            //stage1_Cycle
           1520、          //stage2_FrameTime
           1520、          //stage3_FrameTime
           8、             //stage3_Cycle
           1520           // stage4_FrameTime
       }、
       {//-20>=T
           760、           //stage1_FrameTime
           25、            //stage1_Cycle
           1520、          //stage2_FrameTime
           1520、          //stage3_FrameTime
           8、             //stage3_Cycle
           1520           // stage4_FrameTime
       }
   }
};

const uint8_t  scAN_table[4]={0xC0、0x30、0x0C、0x03};

静态 EPD_Aurora MA_RoomTemp_WaveformTable_Struct*操作__Waveform_param;
静态 COG_LINE_DATA_PACKET_TYPE COG_Line;
静态 EPD_READ_MEMORY_handler _ON_EPD_READ_FLASH;
静态 uint8_t *数据行偶数;
静态 uint8_t *数据行奇数;
静态 uint8_t *数据行扫描;
静态 uint8_t *数据行边界字节;
静态 uint8_t cur_epd_type_index=1;

/**
 *\brief 根据 EPD 的大小和温度进行测量、以获取 STEP_TIME
 *\note 有关更多详细信息、请参阅 COG 文档第5.3节
 *
 *\param EPD_TYPE_INDEX 定义的 EPD 大小
 *
静态空 SET_TEMP_FACTOR (INT8_t 温度){
      ACT_Wave_param=(EP_Aurora ma_RoomTemp_WaveformTable_Struct*)&E_ROOM_Waveform[cur_EPD_TYPED_index][1];//默认


/**
 *\brief 选择 EPD 大小以获取用于驱动 COG 的线路数据阵列
 *
 *\param EPD_TYPE_INDEX 定义的 EPD 大小
 *
void COG_DRIVER_EPDTY_SELECT (void){
   switch (cur_EPD_TYPE_INDEX){
       EPD_144案例:
       DATA_LINE_LEVen =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_144.eval[0];
       DATA_LINE_ODD =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_144.OD[0];
       DATA_LINE_SCAN =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_144.SCAN[0];
       data_line_border_byte =&COG_Line.line_data_by_size.line_data_for_144.bord_byte;
       中断;
       EPD_200案例:
       DATA_LINE_LEVen =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_200.eval[0];
       DATA_LINE_ODD =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_200.ODD;
       DATA_LINE_SCAN =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_200.SCAN[0];
       data_line_border_byte =&COG_Line.line_data_by_size.line_data_for_200.border_byte;
       中断;
       EPD_270案例:
       DATA_LINE_LEVen =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_270.eval[0];
       DATA_LINE_ODD =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_270.ODD;
       DATA_LINE_SCAN =&COG_LINE.LINE_DATA_BY_SIZE.LINE_DATA_OR_270.SCAN[0];
       data_line_border_byte =&COG_Line.line_data_by_size.line_data_for_270.border_byte;
       中断;
   }


/**
 *\brief 开机 COG 驱动程序
 *\note 有关详细流程和说明、请参阅 COG G2文档第3节。
 *

/*
void EPD_POWER_ON (uint8_t EPD_TYPE_INDEX、INT8_t 温度){
   CUR_EPD_TYPE_INDEX = EPD_TYPE_INDEX;

   EPD_Vcc_to_on ();//Vcc 和 Vdd >= 2.7V
   EPD_CS_HIGH ();
   EPD_SPI_Attach ();
   EPD_border_high ();
   EPD_rst_high ();
   DELAY_ms (5);
   EPD_rst_low ();
   DELAY_ms (5);
   EPD_rst_high ();
   DELAY_ms (5);
   //检测温度以确定温度系数
   SET_TEMP_FACTOR (temperature);

*

/**
 *\brief 初始化 COG 驱动程序
 *\note 有关详细流程和说明、请参阅 COG G2文档第4节。
 *
uint8_t initialize_driver (void){

   SET_TEMP_FACTOR (25);
   uint16_t i;
   //清空行缓冲区
   对于(i = 0;i <= line_buffer_data_size;i ++){
       COG_Line.uint8[i]= 0x00;
   }
   //确定用于驱动 COG 的 EPD 大小
   COG_DRIVER_EPDTYPE_SELECT();

   I = 0;

   while (GPIO_getInputPinValue (EPD_BUSY_PORT、EPD_BUSY_PIN)= 1){
       if (((i++)>= 0x0FFF)返回 ERROR_BUSY;
   }

   //检查 COG ID
   if ((SPI_R (0x72、0x00)& 0x0F)!=0x02) return ERROR_COG_ID;

   //禁用 OE
   SPI_SEND_BYTE (0x02、0x40);

   //检查破损情况
   if ((SPI_R (0x0F、0x00)& 0x80)!= 0x80) return error_breakage;

   //节能模式
   SPI_SEND_BYTE (0x0B、0x02);

   //通道选择
   EPD_SPI_SEND (0x01、(uint8_t *)&COG_parameters[cur_EPD_TYPE_index].channel_select、8);

   //高功率模式 OSC 设置
   SPI_SEND_BYTE (0x07、0xD1);

   //功率设置
   SPI_SEND_BYTE (0x08、0x02);

   //设置 Vcom 电平
   SPI_SEND_BYTE (0x09、0xC2);

   //功率设置
   SPI_SEND_BYTE (0x04、0x03);

   //驱动器闩锁打开
   SPI_SEND_BYTE (0x03、0x01);

   //驱动器闩锁关闭
   SPI_SEND_BYTE (0x03、0x00);

   DELAY_ms (5);

   //Chargepump Start
   I=0;
   执行{
       //启动充电泵正极 V
       //VGH 和 VDH 打开
       SPI_SEND_BYTE (0x05、0x01);

       delay_ms (240);

       //启动充电泵负电压
       //VGL 和 VDL 开启
       SPI_SEND_BYTE (0x05、0x03);

       delay_ms (40);

       //设置充电泵
       //Vcom_Driver 至 ON
       //Vcom_Driver 打开
       SPI_SEND_BYTE (0x05、0x0F);

       delay_ms (40);

       //检查 DC/DC
       if ((SPI_R (0x0F、0x00)& 0x40)= 0x40)
       {
           //输出使能以禁用
           SPI_SEND_BYTE (0x02、0x04);
           中断;
       }

   }while (((i++)!= 4);

   if (i>=4) return ERROR_CHARGEPUMP;
   否则返回 RES_OK;



/**
 *\brief 初始化块类型阶段的参数
 *
 *\param S_EPD_Aurorama Aurora 的方框类型波形结构
 *\param block_size 块大小的宽度
 *\param step_size 步长的宽度
 *\param frame_cycle Step Size 的宽度
 *
void stage_init (struct EPD_Aurora ma_Struct* S_EPD_AuroramA、
               uint8_t block_size、uint8_t step_size、
               uint8_t frame_cycle)

   S_EPD_Aurorama->frame_y0 = 0;
   S_EPD_Aurorama->FRAME_Y1 = 176;
   S_EPD_Aurorama->block_y0 = 0;
   S_EPD_Aurorama->BLOCK_Y1 = 0;
   S_EPD_Aurorama->STEP_y0 = 0;
   S_EPD_Aurorama->STEP_Y1 = 0;
   s_EPD_Aurorama->block_size = action__Wave_param->stage1_block1;
   S_EPD_Aurorama->STEP_SIZE =ACT_Wave_param->stage1_step1;
   s_EPD_Aurorama->frame_cycle = act__Wave_param->stage1_frame1;
   S_EPD_Aurorama->NUMBER_OW_STEPs =(COG_PARAMETER[cur_EPD_TYPE_索引].STREAL_SIZE / S_EPD_Aurorama->STEP_SIZE)+(ACT_Wave_param->stage1_block1 / ACT_Wave_param->stage1_step1)-1;



/**
 *\brief for Frame type waveform to update all black / white pattern (帧类型波形更新所有黑白模式)
 *
 *\param bwdata 全屏显示黑色或白色
 *\param work_time the working time
 *
静态内联 void same _data_frame (uint8_t bwdata、uint32_t work _time){
   uint16_t i;
   对于(i = 0;i < COG_parameters[cur_EPD_TYPE_index].Horizontal_size;i++){
       data_line_even [i]=bwdata;
       data_line_ody[i]=bwdata;
   }
   START_EPD_TIMER ();
   操作
   {
       对于(i = 0;i < COG_parameters[cur_EPD_TYPE_index].vertal_size;i++){

           /*每条数据线的扫描字节移位*/
           data_line_scan[(i>>>2)]=scan_table[(i%4)];

           /*发送数据*/
           EPD_SPI_SEND (0x0A、(uint8_t *)&COG_Line.uint8、COG_parameters[cur_EPD_TYPE_index].data_line_size);

           /*打开输出启用*/
           SPI_SEND_BYTE (0x02、0x07);

           DATA_LINE_SCAN[(i>>2)]=0;

       }
   } while (get_counter()<(Work_Time));
       /*停止系统计时器*/
       STOP_EPD_TIMER ();


/**
 *\brief 不向 COG 写入任何内容
 *\note 一行、其所有扫描字节均为0x00
 *
void note_line (void){
   uint16_t i;
   对于(i = 0;i < COG_parameters[cur_EPD_TYPE_index].Horizontal_size;i++){
       DATA_LINE_LEVEN[i]  =  无;
       DATA_LINE_ODD [i]   =  无;
   }



/**
 *\brief 获取阶段1和3的线路数据
 *
 *\note
 *-一个点/像素由2位组成、分别为白色(10)、黑色(11)或无任何内容(01)。
 *  图像数据字节必须分为奇数字节和偶数字节。
 *- COG 驱动程序使用缓冲区写入一行数据(FIFO)-隔行
 *  它的顺序与 COG_G1不同
 *  奇数字节{D (199、y)、D (197、y)、D (195、y)、D (193、y)}、... 、{D (7、y)、D (5、y)、D (3、y)、D (1、y)}
 *  扫描字节{S (96)、S (95)...}
 *  奇数字节 {D(2,y), D(4,y), D(6,y), D(8,y)},... ,{D(194,y),D(196,y),D(198,y), D(200,y)}
 *-有关驱动级的更多详细信息、请参阅 COG G2文档第5节。
 *
 *\param image_ptr 存储将发送到 COG 的映像的内存指针
 *\param stage_no 分配的将继续的阶段编号
 *

void read_line_data_handle (uint8_t * image_prt、uint8_t stage_no)

   int16_t x、k;
   uint8_t temp_Byte;//临时存储以进行图像数据检查
   k=COG_parameters[cur_EPD_TYPE_index].Horizontal_size-1;
   对于(x =0;x < COG_parameters[cur_EPD_TYPE_index].Horizontal;x++){
               temp_Byte =* image_prt ++;
               switch (stage_no){
                   案例 stage1://反转图像
                   /*第1阶段的示例以获取偶数和奇数数据。 它的顺序与 G1不同。
                   *+--- +-----+--+---+---+---+---+-+-++
                   *|        |bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
                   *|temp_Byte+-++-++-++-++-++------+--+--++
                   *|        | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
                   *+--- +-----+---+---+----+----+--+*/
                   DATA_LINE_ODD [x]      =((temp_BYTE & 0x40)? BLACK3 :WHITE3);// WHITE3 = 0x80 = 1000 0000
                   DATA_LINE_ODD 位[x]     |=(temp_BYTE & 0x10)? BLACK2 :WHITE2);// BLACK2 = 0x30 = 0011 0000
                   DATA_LINE_ODD 位[x]     |=(temp_BYTE & 0x04)? BLACK1 :WHITE1);// BLACK1 = 0x0C = 0000 1100
                   DATA_LINE_ODD 位[x]     |=(temp_BYTE & 0x01)? BLACK0 :WHITE0);// WHITE0 = 0x02 = 0000 0010
                   /* data_line_ody[x]= 1000 0000 | 0011 0000 | 0000 1100 | 0000 0010 = 1011 1110 => 1011 1110
                   *查看下表中的偶数数据行*/

                   DATA_LINE_LEVEN[k]   =((temp_BYTE & 0x80)? BLACK0 :WHITE0);// BLACK0 = 0x03 = 0000 0011
                   DATA_LINE_LEVEN[k]  |=(temp_BYTE & 0x20)? BLACK1 :WHITE1);// BLACK1 = 0x0C = 0000 1100
                   DATA_LINE_LEVEN[k]  |=(temp_BYTE & 0x08)? BLACK2 :WHITE2);// WHITE2 = 0x20 = 0010 0000
                   DATA_LINE_LEVEN[k--]|=(temp_BYTE & 0x02)? BLACK3 :WHITE3);// WHITE3 = 0x80 = 1000 0000
                   /* data_line_eval[k]= 0000 0011 | 0000 1100 | 0010 0000 | 1000 0000 = 1010 1111 => 1111 1010
                   *请参阅下表中的奇数数据行
                   *+--- +-----+--+---+---+---+---+-+-++
                   *|        |bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
                   *|temp_Byte+-++-++-++-++-++------+--+--++
                   *|        | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
                   *+--- +-----+--+---+---+---+---+-+-++
                   *|颜色  | W | B | W | W | B | W | B | B | W =白色、B =黑色、N =无任何变化
                   *+--- +-----+--+---+---+---+---+-+-++
                   *|阶段1 | B | W | B | B | W | B | W | W | W |反转
                   *+--- +-----+--+---+---+---+---+-+-++
                   *|输入  | 11 | 10 | 11 | 11 | 10 | 11 | 10 | 10 | 10 | W=10、B=11、N=01
                   *+--- +-----+--+---+---+---+---+-+-++
                   *|偶数数据| 11 |   | 11 |   | 10 |   | 10 |   ||= 1111 1010
                   *+--- +-----+--+---+---+---+---+-+-++
                   *|奇数数据|   || 10 |   | 11 |   |   || 10 |= 1011 1110
                   *+--- +-----+---+---+----+----+--+*/
                   中断;
                   Case Stage3://新建图像
                       DATA_LINE_ODD [x]        =((temp_BYTE & 0x40)? WHITE3 :BLACK3 );
                       DATA_LINE_ODD 位[x]       |=(temp_BYTE & 0x10)? WHITE2 :BLACK2 );
                       DATA_LINE_ODD 位[x]       |=(temp_BYTE & 0x04)? WHITE1 :BLACK1 );
                       DATA_LINE_ODD 位[x]       |=(temp_BYTE & 0x01)? WHITE0 :BLACK0 );

                       DATA_LINE_LEVEN[k]       =((temp_BYTE & 0x80)? WHITE0 :BLACK0 );
                       DATA_LINE_LEVEN[k]      |=(temp_BYTE & 0x20)? WHITE1 :BLACK1 );
                       DATA_LINE_LEVEN[k]      |=(temp_BYTE & 0x08)? WHITE2 :BLACK2 );
                       DATA_LINE_LEVEN[k--]    |=(temp_BYTE & 0x02)? WHITE3 :BLACK3 );
                   中断;
               }
       }



/**
 *\简述 基本功能、以处理框架和块类型的驱动阶段
 *
 *\note
 *-在 Aurorama_G2型 EPD 上完成图像更新周期有3个阶段。
 *-有关驱动级的更多详细信息、请参阅 COG G2文档第5.4节
 *
 *\param image_ptr 存储将发送到 COG 的映像的映像数组的指针
 *\param image_data_address 存储映像的存储器地址
 *\param stage_no 分配的将继续的阶段编号
 *\param lineoffset 行数据偏移
 *
void stage_handle_Base (uint8_t * image_prt、long image_data_address、
                       uint8_t stage_no、uint8_t 线路偏移)

   struct EPD_Aurora ma_Structurt S_EPD_AuroramA;
   int16_t cycle、m、i;//m=阶跃数
   //uint8_t isLastframe = 0; //如果它是第一个扫描线上的最后一个帧,则不发送任何内容
   uint8_t isLastBlock=0;     //如果块的起始行在 EPD 的有效范围内
   int16_t scanline_no=0;
   uint8_t *操作块端口;
   long action_block_address;
   uint8_t byte_array[line_buffer_data_size];
   /**阶段2:黑白图像,帧类型*/
   if (stage_no=stage2)
   {
       for (i=0;i stage2_cycle;i++)
       {
           同一数据帧(all_black、action__Wave_param->stage2_t1);
           Same _data_frame (all_white、action__Wave_param->stage2_t2);
       }
       返回;
   }
   /**阶段1和3,块类型*/
   //缺省情况下,stage1和 stage3的帧/块/步长是相同的。
   Stage_init (&S_EPD_AuroramA、
               action__Wave_param->stage1_block1,
               action__Wave_param->stage1_step1,
               action__Wave_param->stage1_frame1);

    /*重复帧数*/
    对于(cycle = 0;cycle <(循环<)(S_epd_AuroraMa.frame_cycle);cycle++)
    {

       // if (cycle =(S_epd_AuroraMa.frame_cycle - 1)) isLastframe = 1;

        isLastBlock = 0;
        S_EPD_Aurorama.step_y0 = 0;
        S_EPD_Aurorama.step_Y1 = S_EPD_Aurorama.step_size;
        S_EPD_Aurorama.block_y0 = 0;
        S_EPD_Aurorama.block = 0;
        /*移动步数*/
        对于(m = 0;m < S_EPD_Aurorama.number_for_steps;m++)
        {
            S_EPD_Aurorama.block_y1 += S_EPD_Aurorama.step_size;
            S_EPD_Aurorama.block_y0 = S_EPD_Aurorama.block_Y1 - S_EPD_Aurorama.block_size;
           /*如果块不在 EPD 的有效范围内、则复位 block_y0=frame_y0 *
            if (S_EPD_Aurorama.block_y0 < S_epd_AuroraMa.frame_y0) S_EPD_Aurorama.block_y0 = S_epd_AuroraMa.frame_y0;

           /*如果块的起始线在 EPD 的有效范围内*/
            如果(S_EPD_Aurorama.block_y1 = S_EPD_Aurorama.block_size) isLastBlock = 1;

            if (image_prt!=NULL)
            {
                action_block_prt =(image_prt +(int)(S_EPD_Aurorama.block_y0*lineoffset);
            }
            否则、如果(_ON_EPD_READ_FLASH!=NULL) //读取块范围内的行数据、请先读取
            {
               action_block_address=image_data_address+(long)(S_EPD_Aurorama.block_y0*lineoffset);
               _ON_EPD_READ_FLASH (ACT_BLOCK_ADDRESS、(uint8_t *)&byte_array、
                                   COG_parameters[cur_EPD_TYPE_index].Horizontal_size);
               action_block_prt =(uint8_t *)&byte_array;
            }
           /*更新行数据*/
            对于(i = S_EPD_Aurorama.block_y0;i < S_EPD_Aurorama.block_Y1;i++)
            {

                如果(i >= COG_parameters[cur_EPD_TYPE_index].vertal_size)中断;
                //if (isLastframe &&)
                如果(
                 isLastBlock &&(I <(S_EPD_Aurorama.step_size + S_EPD_Aurorama.block))
                 {
                     NOWITY_LINE();
                 }
                 其他
                 {
                     read_line_data_handle (action_block_prt、stage_no);
                 }

               if (_on_epd_read_flash!=NULL)   //读取块范围内的行数据
               {
                   action_block_address +=lineoffset;
                   _ON_EPD_READ_FLASH (ACT_BLOCK_ADDRESS、(uint8_t *)&byte_array、
                   COG_parameters[cur_EPD_TYPE_index].Horizontal_size);
                   action_block_prt =(uint8_t *)&byte_array;
               }
               否则 action_block_prt +=lineoffset;

               scanline_no=(COG_parameters[cur_EPD_TYPE_index].vertal_size-1)-i;

               /*每条数据线的扫描字节移位*/
               data_line_scan[(scanline_no>>2)]= scan_table[(scanline_no%4)];

               /* 边框使用内部信号控制字节。 *
               *DATA_LINE_border_Byte=0x00;

               /*发送数据*/
               EPD_SPI_SEND (0x0A、(uint8_t *)&COG_Line.uint8、
               COG_parameters[cur_EPD_TYPE_index].data_line_size);


               /*打开输出启用*/
               SPI_SEND_BYTE (0x02、0x07);

               data_line_scan[(scanline_no>>2)]=0;

            }
        }

   }


/**
 *\简述 从图像阵列(image_data.h)到 COG 的驱动阶段
 *
 *\param image_ptr 存储将发送到 COG 的映像的映像数组的指针
 *\param stage_no 分配的将继续的阶段编号
 *\param lineoffset 行数据偏移
 *
void stage_handle (uint8_t * image_prt、uint8_t stage_no、uint8_t 线路偏移)

   Stage_Handle_Base (image_prt、address_NULL、stage_no、lineoffset);


/**
 *\简述 从内存到 COG 的驱动级
 *
 *\note
 *-如果图像数据是图像数据、则此处为开发人员添加了此函数
 *  存储在闪存中。
 *
 *\param image_data_address 存储映像的闪存地址
 *\param stage_no 分配的将继续的阶段编号
 *\param lineoffset 行数据偏移
 *
静态空 stage_handle_ex (long image_data_address、uint8_t stage_no、uint8_t lineoffset){
   Stage_Handle_Base (NULL、IMAGE_DATA_ADDRESS、STAGE_NO、lineOFFSET);


/**
 *\brief 将图像数据从存储器阵列(image_data.h)写入 EPD
 *
 *\param previous_image_ptr 存储前一图像的内存指针
 *\param new_image_ptr 存储新映像的内存指针
 *
void display_from _array_prt (uint8_t * previous_image_ptr、
       uint8_t * new_image_ptr){
   _on_epd_read_flash=0;
   Stage_Handle (new_image_ptr、stage1、COG_parameters[cur_EPD_type_index].Horizontale_size);
   Stage_Handle (new_image_ptr、stage2、COG_parameters[cur_EPD_type_index].Horizontale_size);
   Stage_Handle (new_image_ptr、Stage3、COG_parameters[cur_EPD_type_index].Horizontale_size);


/**
 *\brief 将图像数据从闪存写入 EPD
 *\note 如果图像数据是图像数据、则此处为开发人员添加了此函数
 *存储在闪存中。
 *
 *\param previous_image_flash_address 存储前一映像的存储器的起始地址
 *\param new_image_flash_address 存储新映像的存储器的起始地址
 *\param on_EPD_Read_FLASH 开发人员需要创建一个外部函数来读取闪存
 *
void display_from _flash_prt (long previous_image_flash_address、
   long new_image_flash_address、EPD_read_memory_handler ON_EPD_read_flash){

   uint8_t line_len;
   LINE_LEN=Line_Offset (cur_EPD_TYPE_INDEX);
   if (line_len=0) line_len=COG_parameters[cur_EPD_type_index].Horizontal_size;

   _on_epd_read_flash=on_epd_read_flash;
   Stage_handle_ex (new_image_flash_address、stage1、line_len);
   Stage_handle_ex (new_image_flash_address、stage2、line_len);
   Stage_handle_ex (new_image_flash_address、stage3、line_len);



/**
 *\brief 将虚拟线路写入 COG
 *\请注意一行、所有数据和扫描字节均为0x00
 *
void dummy_line (void){
   uint8_t i;
   对于(i = 0;i <(COG_parameters[cur_EPD_TYPE_索引].vertal_size/8);i++){
       COG_Line.uint8[i]= 0x00;
   }

   /*发送数据*/
   EPD_SPI_SEND (0x0A、(uint8_t *)&COG_Line.uint8、COG_parameters[cur_EPD_TYPE_index].data_line_size);

   /*打开输出启用*/
   SPI_SEND_BYTE (0x02、0x07);




/**
*\brief 写入边界(输入)虚拟线路
*
静态空 border_dummy_line (空)

   uint16_t   i;
   对于(i =0;i < COG_parameters[cur_EPD_TYPE_index].Horizontal_size;i++)
   {
       DATA_LINE_ODD [I]=0x55;
       DATA_LINE_LEVEN[I]=0x55;
   }

   对于(i = 0;i <(COG_parameters[cur_EPD_TYPE_索引].vertal_size/8);i++)
   {
       DATA_LINE_SCAN[i]= 0x00;
   }

   *DATA_LINE_border_Byte=border_byte_W;
   //编写一条 Borde (B)虚拟线
   EPD_SPI_SEND (0x0a、(uint8_t *)&COG_Line.uint8、COG_parameters[cur_EPD_TYPE_index].data_line_size);
   //打开 OE
   SPI_SEND_BYTE (0x02、0x07);



/**
 *\brief 将 Nothing Frame 写入 COG
 *\请注意一个帧、所有 D (x、y)都是 N (01)。 0101=0x55=无
 *
void note_frame (void){
   uint16_t i;
   对于(i = 0;i < COG_parameters[cur_EPD_TYPE_index].Horizontal_size;i++){
       data_line_even [i]=无;
       data_line_ody[i]=无;
   }

   对于(i = 0;i < COG_parameters[cur_EPD_TYPE_index].vertal_size;i++){

       /*每条数据线的扫描字节移位*/
       data_line_scan[(i>>>2)]=scan_table[(i%4)];

       /*发送数据*/
       EPD_SPI_SEND (0x0A、(uint8_t *)&COG_Line.uint8、COG_parameters[cur_EPD_TYPE_index].data_line_size);

       /*打开输出启用*/
       SPI_SEND_BYTE (0x02、0x07);

       DATA_LINE_SCAN[(i>>2)]=0;
   }

/**
*\brief 关闭 COG 驱动程序
*\note 有关详细流程和说明、请参阅 COG G2文档第6节。
*
uint8_t power_off (void){

   NOTE_FRAME();
   if (cur_EPD_type_index=EPD_144 || cur_EPD_type_index=EPD_200)
   {
       border_dummy_line ();
       delay_ms (200);
   }


   if (cur_epd_type_index=epd_270){
       dummy_line();
       delay_ms (25);
       EPD_border_low ();
       delay_ms (200);
       EPD_border_high ();
   }

   SPI_SEND_BYTE (0x0B、0x00);

   //打开锁存复位
   SPI_SEND_BYTE (0x03、0x01);
   //关闭电荷泵 Vcom
   SPI_SEND_BYTE (0x05、0x03);
   //关闭电荷泵负电压
   SPI_SEND_BYTE (0x05、0x01);
   delay_ms (120);
   SPI_SEND_BYTE (0x04、0x80);
   //关闭所有电荷泵
   SPI_SEND_BYTE (0x05、0x00);

   //关闭 OSC
   SPI_SEND_BYTE (0x07、0x01);
   delay_ms (50);

  spi_detach ();
   EPD_border_low ()
   //EPD_border_low ();
   EPD_panel_low ()
   ///EPD_Vcc_turn _off ();
   delay_ms (10);

   cs_low();
   //EPD_cs_low ();
   EPD_RESET_LOW ()
  // EPD_rst_low ();

   EPD_DELOAD_HIGH ()
   //EPD_DELOAD_HIGH ();
   delay_ms (150);
   EPD_DELOAD_LOW ()
   //EPD_DELOAD_LOW ();


   返回 RES_OK;


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!  

    您已经发布了一大部分代码、这对于我来说太多了、无法进行调试。 请将您的代码减少到一个仍然存在问题的较小代码集、以便更易于查看。

    [引用 user="Sladjan Dragicevic">工作频率大致相同。 MSP430FR5994 = 24MHz、 MSP430F5529 = 25MHz。[/QUERP]

    MSP430FR5994的最大频率为16MHz。 以上任何内容超出规格、我无法保证可靠运行。

    此致、  
    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Caleb、

    抱歉、部分代码。 我已经将其简化为失速的函数。

    是的、根据 FR5994的规格、工作频率为16MHz。 我已将其超频至24、以更快地运行。 它的运行速度比在16MHz 上的运行速度快一点。 但即使在24MHz 下、它也比在25MHz 下 MSP430F5529上运行的相同代码慢10倍以上。

    提供失速的功能如下所示。 在这部分代码中调用的函数在原始帖子中提供。

    void stage_handle_Base (uint8_t * image_prt、long image_data_address、
                           uint8_t stage_no、uint8_t 线路偏移)

       struct EPD_Aurora ma_Structurt S_EPD_AuroramA;
       int16_t cycle、m、i;//m=阶跃数
       //uint8_t isLastframe = 0; //如果它是第一个扫描线上的最后一个帧,则不发送任何内容
       uint8_t isLastBlock=0;     //如果块的起始行在 EPD 的有效范围内
       int16_t scanline_no=0;
       uint8_t *操作块端口;
       long action_block_address;
       uint8_t byte_array[line_buffer_data_size];
       /**阶段2:黑白图像,帧类型*/
       if (stage_no=stage2)
       {
           for (i=0;i stage2_cycle;i++)
           {
               同一数据帧(all_black、action__Wave_param->stage2_t1);
               Same _data_frame (all_white、action__Wave_param->stage2_t2);
           }
           返回;
       }
       /**阶段1和3,块类型*/
       //缺省情况下,stage1和 stage3的帧/块/步长是相同的。
       Stage_init (&S_EPD_AuroramA、
                   action__Wave_param->stage1_block1,
                   action__Wave_param->stage1_step1,
                   action__Wave_param->stage1_frame1);

        /*重复帧数*/
        对于(cycle = 0;cycle <(循环<)(S_epd_AuroraMa.frame_cycle);cycle++)
        {

           // if (cycle =(S_epd_AuroraMa.frame_cycle - 1)) isLastframe = 1;

            isLastBlock = 0;
            S_EPD_Aurorama.step_y0 = 0;
            S_EPD_Aurorama.step_Y1 = S_EPD_Aurorama.step_size;
            S_EPD_Aurorama.block_y0 = 0;
            S_EPD_Aurorama.block = 0;
            /*移动步数*/
            对于(m = 0;m < S_EPD_Aurorama.number_for_steps;m++)
            {
                S_EPD_Aurorama.block_y1 += S_EPD_Aurorama.step_size;
                S_EPD_Aurorama.block_y0 = S_EPD_Aurorama.block_Y1 - S_EPD_Aurorama.block_size;
               /*如果块不在 EPD 的有效范围内、则复位 block_y0=frame_y0 *
                if (S_EPD_Aurorama.block_y0 < S_epd_AuroraMa.frame_y0) S_EPD_Aurorama.block_y0 = S_epd_AuroraMa.frame_y0;

               /*如果块的起始线在 EPD 的有效范围内*/
                如果(S_EPD_Aurorama.block_y1 = S_EPD_Aurorama.block_size) isLastBlock = 1;

                if (image_prt!=NULL)
                {
                    action_block_prt =(image_prt +(int)(S_EPD_Aurorama.block_y0*lineoffset);
                }
                否则、如果(_ON_EPD_READ_FLASH!=NULL) //读取块范围内的行数据、请先读取
                {
                   action_block_address=image_data_address+(long)(S_EPD_Aurorama.block_y0*lineoffset);
                   _ON_EPD_READ_FLASH (ACT_BLOCK_ADDRESS、(uint8_t *)&byte_array、
                                       COG_parameters[cur_EPD_TYPE_index].Horizontal_size);
                   action_block_prt =(uint8_t *)&byte_array;
                }
               /*更新行数据*/
                对于(i = S_EPD_Aurorama.block_y0;i < S_EPD_Aurorama.block_Y1;i++)
                {

                    如果(i >= COG_parameters[cur_EPD_TYPE_index].vertal_size)中断;
                    //if (isLastframe &&)
                    如果(
                     isLastBlock &&(I <(S_EPD_Aurorama.step_size + S_EPD_Aurorama.block))
                     {
                         NOWITY_LINE();
                     }
                     其他
                     {
                         read_line_data_handle (action_block_prt、stage_no);
                     }

                   if (_on_epd_read_flash!=NULL)   //读取块范围内的行数据
                   {
                       action_block_address +=lineoffset;
                       _ON_EPD_READ_FLASH (ACT_BLOCK_ADDRESS、(uint8_t *)&byte_array、
                       COG_parameters[cur_EPD_TYPE_index].Horizontal_size);
                       action_block_prt =(uint8_t *)&byte_array;
                   }
                   否则 action_block_prt +=lineoffset;

                   scanline_no=(COG_parameters[cur_EPD_TYPE_index].vertal_size-1)-i;

                   /*每条数据线的扫描字节移位*/
                   data_line_scan[(scanline_no>>2)]= scan_table[(scanline_no%4)];

                   /* 边框使用内部信号控制字节。 *
                   *DATA_LINE_border_Byte=0x00;

                   /*发送数据*/
                   EPD_SPI_SEND (0x0A、(uint8_t *)&COG_Line.uint8、
                   COG_parameters[cur_EPD_TYPE_index].data_line_size);


                   /*打开输出启用*/
                   SPI_SEND_BYTE (0x02、0x07);

                   data_line_scan[(scanline_no>>2)]=0;

                }
            }

       }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Sladjan、

    我不建议您对器件进行超频、我怀疑频率增加与等待状态相结合是导致问题的原因。 当您超出规格运行时、我无法保证器件正常运行、并且器件可能会意外运行。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为代码针对 MSP430F5529进行了优化,该代码是由 Pervasive 编写的,这就是为什么它在 MSP430FR5994上运行缓慢的原因。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    MSP430F5529和 MSP430FR5994具有相同的 CPUXV2、因此我怀疑优化是问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Caleb:

    感谢你的建议。

    超频不是这里的问题。 当我将两个控制器的时钟设置为16MHz 时、代码在 MPS430F5529上的运行速度仍然是 MSP430FR5994上的10倍。

    代码本身未针对任何这些进行优化。 这是一个 C 语言代码、如果主时钟的速度相同、那么它应该在两个上以相同的速度运行。

    此致、

    斯拉德詹

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Zrno Soli、

    代码本身未针对任何控制器进行优化。 这些编译器可能会产生影响、但我对此有疑问。

    同一代码在一个 MCU 上的运行速度不能比在另一个 MCU 上的运行速度慢得多。 即使它们的速度与主时钟相同。

    如果我在这方面没有得到 TI 的任何支持、我就不得不放弃 MSP430FR5994上的开发。
    并且可能永远放弃 TI MCU。

    这里的问题是不可接受的!

    此致、
    斯拉德詹
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Sladjan、

    在16MHz 时、FR5994中仍使用等待状态。 我没有看到任何明显的硬件差异、除此之外、可能会导致问题(例如硬件乘法器等)。 您提到、出现问题的代码部分是经常访问 FRAM。 我认为一个很好的测试是在 FR5994上无需等待状态的8MHz 频率下运行两个器件、并比较执行时间。 您能否尝试一下并告诉我结果?

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Caleb、

    我做了你的建议。 两个 MCU 均设置为8MHz。 情况大致相同。 FR5994的速度要慢得快。 比如10次。

    此致、

    斯拉德詹

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sladjan、

    这有点令人困惑。 如何测量两组代码之间的时间差?

    代码相当难读取、因此我不确定是什么原因导致了此问题。 我确实看到您以13.5MHz 的频率运行 SPI、相对速度很快。 您确定不超过此器件上的最大 SPI 通信速度吗?  您可以在《MSP430 MCU 上常见 eUSCI 和 USCI 串行通信问题解决方案》 第4.2节中找到有关如何执行计算的说明。

    此致、  
    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Caleb、

    首先、很抱歉、我之前说过 SPI CLK 为13.5、而是12 MHz。

    我已经在各种 SPI 时钟速度下测试了 MSP4305994。 (从器件支持高达大约13MHz 的频率)
    5MHz、6MHz、10MHz 或12MHz 的 SPICLK 之间没有很大差异。 (支持12MHz、传输运行良好)
    SPI 传输速度很快、比下一次传输之前存在大延迟时间更长。 每次传输都在要更新发送数据的循环中进行声明。
    在 MSP430F5529上没有该延迟。 因此、在两次传输之间、FR5994执行的代码比 F5529慢10倍。


    总之、SPI 运行良好、但 MCU 速度太慢。(具体由规格决定。 应该快一点!)

    为了测量时间、我使用了秒表。 我的人工反应时间包括在内、但两个 MCU 之间的差异很明显。

    期待更多支持。
    此致 Sladjan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Sladjan、

    我对迟迟不作出答复表示歉意。 我一直在查看您的代码、但我仍然找不到您遇到缓慢行为的原因。 您是否取得了任何进展? 如果没有显示屏来测试代码、我恐怕无法完成更多工作。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Caleb、

    答复还可以。

    我已经尝试了各种方法来加快速度、但没有成功。

    尝试在 TI 和其他供应商的类似 MCU 上以相同的频率运行代码。 MSP430FR5994简单易行、速度也很慢。 已使用 MSP430F5529检查架构。 它是相同的。

    毕竟、我找不到问题或速度提升。

    扩展板是普遍使用的 EPD 扩展板 Gen2 (EXT2)- 02。 使用的显示器是 ETC G2 Aurora Ma (2英寸)。

    此致、

    斯拉德詹