我有一个模拟设备的DAC8562。这是一份数据表:
http://www.analog.com/media/en/technical-documentation/data-sheets/DAC8562.pdf
它是一个并行的12位DAC。我有一个用C语言编写的函数,它控制GPIO引脚将输入值锁存到DAC。我的问题是我的功能很慢。这是代码:
void setOut(uint16_t data) {
//Set DATA
if (data & 0x01) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN2);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN2);
}
if (data & 0x02) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN0);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN0);
}
if (data & 0x04) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN1);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN1);
}
if (data & 0x08) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN7);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN7);
}
if (data & 0x10) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN6);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN6);
}
if (data & 0x20) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN4);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN4);
}
if (data & 0x40) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN6);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN6);
}
if (data & 0x80) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN6);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN6);
}
if (data & 0x100) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN7);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN7);
}
if (data & 0x200) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN3);
}
if (data & 0x400) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN1);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN1);
}
if (data & 0x800) {
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN5);
} else {
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN5);
}
// Set CE Low
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN4);
// Set CE High
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN4);}
问题是电路板的布局需要我正在使用的特定端口/引脚分配。 截至目前,我正在单独检查每个位,并匹配该位表示高或低的引脚输出。有没有更有效的方法呢?
其他信息: 我正在使用MSP432P401R作为微控制器。 我正在使用TI的驱动程序库来控制GPIO。
答案 0 :(得分:1)
更好的代码智能! 你有:
解决方案1:
struct param_t
{
uint8_t bitmask;
uint??_t gpio_port;
uint??_t gpio_pin;
}
const param_t param[XXXX] =
{
{0x01, GPIO_PORT_P4, GPIO_PIN2},
{0x02, GPIO_PORT_P4, GPIO_PIN0},
{...},
}
void setOut(uint16_t data)
{
for(int i=0; i<XXXX; i++)
{
if(data & param[i].bitmask)
{
MAP_GPIO_setOutputHighOnPin(param[i].gpio_port, param[i].gpio_pin)
}
else
{
MAP_GPIO_setOutputLowOnPin(param[i].gpio_port, param[i].gpio_pin)
}
}
}
解决方案2:
const callback_t callback[2] =
{
MAP_GPIO_setOutputHighOnPin,
MAP_GPIO_setOutputLowOnPin
}
void setOut(uint16_t data)
{
callback[(int)(data & 0x01 == 0)](GPIO_PORT_P4, GPIO_PIN2};
callback[(int)(data & 0x02 == 0)](GPIO_PORT_P4, GPIO_PIN0};
...
}
解决方案3 :(不确定是否可行)
之后我认为MAP_GPIO_setOutputXxxxOnPin很慢。它读取修改然后写回寄存器。您应该在同一端口上多次调用该函数,而不是在同一端口上多次调用该函数,在内存中本地修改其所有引脚,然后再将其写回一次。
答案 1 :(得分:0)
哦,有很多优化空间!
用快速原始寄存器写:
替换这个丑陋的MAP_GPIO_setOutputXXX ()
include "msp432.h" // it is from TI DriverLib too
...
if (data & 0x01)
P4OUT |= (1<<2);
else
P4OUT &= ~(1<<2);
// and so on ...
使用Cortex的核心功能bit banding:
,而不是逐位运算// Convert SRAM address
#define BITBAND_SRAM_REF 0x20000000
#define BITBAND_SRAM_BASE 0x22000000
#define BITBAND_SRAM(a,b) HWREG32((BITBAND_SRAM_BASE + (&(a) - BITBAND_SRAM_REF)*32 + (b*4)))
// Convert PERI address
#define BITBAND_PERI_REF 0x40000000
#define BITBAND_PERI_BASE 0x42000000
#define BITBAND_PERI(a,b) HWREG32((BITBAND_PERI_BASE + (&(a) - BITBAND_PERI_REF)*32 + (b*4)))
...
if (data & 0x01)
BITBAND_PERI (P4OUT, 2) = 1;
else
BITBAND_PERI (P4OUT, 2) = 0;
...
修改位带方法,删除if()
语句。这是可能的,因为对于位带写道,只有最低有效位是重要的。
BITBAND_PERI (P4OUT, 2) = data >> 0; // bit 0
BITBAND_PERI (P4OUT, 0) = data >> 1; // bit 1
BITBAND_PERI (P6OUT, 1) = data >> 2; // bit 2
BITBAND_PERI (P2OUT, 7) = data >> 3; // bit 3
// etc