主题中讨论的其他器件: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;
}