在Raspberry PI上,NJU6061的LED控制模块的驱动

NJU6061是一个LED的控制模块,可以通过PWM的方式对三色的LED灯进行控制,从而达到显示多种颜色。NJU6061可以控制3路PWM信号。具体的连接方式可参考NJU6061的datasheet。NJU6061可以输出2种模式:1.固定的PWM输出 2.以扫描形式输出,即是以颜色渐变的方式来改变颜色。这里只测试固定PWM输出。

本驱动所使用的RPi的GPIO与NJU6061上的连接方式为:

//gpio.c

RPi GPIO Num   NJU6061 Pin

3   RSTb  

21 CS

39 CLK

38 DAT


本驱动使用了之前写过的RPi的GPIO操作的库。代码如下:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/ioctl.h>


#define BCM2708_PERI_BASE                     0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000)
#define BLOCK_SIZE (4*1024)


#define INPUT 0
#define OUTPUT 1
#define LOW 0
#define HIGH 1


static volatile uint32_t *gpio ;




static uint8_t gpioToGPSET [] =
{
   7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
   8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
} ;


// gpioToGPCLR:
// (Word) offset to the GPIO Clear registers for each GPIO pin


static uint8_t gpioToGPCLR [] =
{
  10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
} ;


// gpioToGPFSEL:
// Map a BCM_GPIO pin to it's Function Selection
// control port. (GPFSEL 0-5)
// Groups of 10 - 3 bits per Function - 30 bits per port


static uint8_t gpioToGPFSEL [] =
{
  0,0,0,0,0,0,0,0,0,0,
  1,1,1,1,1,1,1,1,1,1,
  2,2,2,2,2,2,2,2,2,2,
  3,3,3,3,3,3,3,3,3,3,
  4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,
} ;




// gpioToShift
// Define the shift up for the 3 bits per pin in each GPFSEL port


static uint8_t gpioToShift [] =
{
  0,3,6,9,12,15,18,21,24,27,
  0,3,6,9,12,15,18,21,24,27,
  0,3,6,9,12,15,18,21,24,27,
  0,3,6,9,12,15,18,21,24,27,
  0,3,6,9,12,15,18,21,24,27,
} ;






int GPIOSetup()
{
int fd = -1;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
{
printf ("wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
return 0;
}


// GPIO:


gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
if ((int32_t)gpio == -1)
{
printf("wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ;
return 0;
}
return 1;
}


int GPIOSetPinMode(int nPin, int mode)
{
int    fSel = 0, shift = 0;
    fSel    = gpioToGPFSEL [nPin] ;
    shift   = gpioToShift  [nPin] ;


#if 0
if (mode == INPUT)
 *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
else if (mode == OUTPUT)
 *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
#else
//printf("function sel register = %p\n",gpio + fSel);
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (mode << shift) ;


#endif
return 0;
}
int GPIOGetPinMode(int nPin)
{
int mode = 0;
int    fSel = 0, shift = 0;
    fSel    = gpioToGPFSEL [nPin] ;
    shift   = gpioToShift  [nPin] ;
//printf("function sel register = %p\n",gpio + fSel);
return ((*(gpio + fSel))&(7<<shift))>>shift;
}


int GPIOSetPin(int nPin, int value)
{
    if (value == LOW)
      *(gpio + gpioToGPCLR [nPin]) = 1 << (nPin & 31) ;
    else
      *(gpio + gpioToGPSET [nPin]) = 1 << (nPin & 31) ;
}

//gpio.h

#ifndef RPi_GPIO_H__
#define RPi_GPIO_H__


#ifdef __cplusplus
extern "C" {
#endif
int GPIOSetup();
int GPIOSetPinMode(int nPin, int mode);
int GPIOSetPin(int nPin, int value);






#ifdef __cplusplus
}
#endif


#endif

测试的代码如下:

其中有两种模式:1.三种颜色LED同时发光,这时显示的是白光。2.分别测试三种RGB色及通过改变PWM的占空比来调节其明暗,具体步骤请参考代码。


//ledtest.c

#include "gpio.h"
#include <sys/time.h>


#define INPUT 0
#define OUTPUT 1
#define LOW 0
#define HIGH 1


#define CS 21
#define RSTb 3
#define CLK 39
#define DAT 38


#define RED 0x60
#define GREEN 0x70
#define BLUE 0x80
void delay (unsigned int howLong)
{
struct timespec sleeper, dummy ;


sleeper.tv_sec  = (time_t)(howLong / 1000) ;
sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;


nanosleep (&sleeper, &dummy) ;
}


void initialize()
{
GPIOSetup();
GPIOSetPinMode(RSTb,OUTPUT);
GPIOSetPinMode(CS,OUTPUT);
GPIOSetPinMode(CLK,OUTPUT);
GPIOSetPinMode(DAT,OUTPUT);


//hardware reset
GPIOSetPin (RSTb, LOW);
delay(10);
GPIOSetPin (RSTb, HIGH);
delay(1);



GPIOSetPin (CS, LOW);
GPIOSetPin(DAT,HIGH);
GPIOSetPin(CLK,HIGH);


}
void writeData(unsigned char cData)
{
unsigned char tmp = cData;
int i = 0;
GPIOSetPin (CS, LOW);
delay(1);
GPIOSetPin (CS, HIGH);
delay(1);


// printf("dat = ");
for(i = 7; i >=0; i--)
{
GPIOSetPin (CLK,LOW);
delay(1);
GPIOSetPin(DAT,((cData&(1<<i))==(1<<i))?HIGH:LOW);
// printf("%d ",((cData&(1<<i))==(1<<i))?HIGH:LOW);
delay(1);
GPIOSetPin (CLK,HIGH);
delay(1);
}
// printf("\n");

GPIOSetPin (CS, LOW);
}


int main(int argc, char** argv)
{
int mode = 0;
GPIOSetup();
initialize();
writeData(0x11); //frequency set
writeData(0x20); //disable sweep fucntion


if (argc !=2)
printf("Usage: ledtest mode.\n\tmode = 0 single pwm test mode \n\tmode=1 automatic pwm mode");


mode = atoi(argv[1]);
printf("mode = %d\n",mode);
if(mode == 0)
{

//display white color
writeData(BLUE|0xf); //set PWM data = 1011 duty cycle 59/128 for LED1 Blue
writeData(GREEN|0xf); //LED2 Green
writeData(RED|0xf); //LED3  Red
printf("press enter to continue.\n");
getchar();

}
else if(mode == 1)
{
for(;;)
{
int i = 0;
int nBrightness = 0;
unsigned int mSec = 1000;
for(i = 3; i >=0; i--)
{
//printf("0x80&(4*i) = 0x%x\n",0x80|(1<<i));
nBrightness = (1<<i);
printf("brightness = %d%%\n",100*(i+1)/4);


printf("Red.\n");
writeData(BLUE); //LED1 Blue
writeData(GREEN); //LED2 Green
writeData(RED|nBrightness); //LED3  Red
delay(mSec);


printf("Green.\n");
writeData(BLUE); //LED1 Blue
writeData(GREEN|nBrightness); //LED2 Green
writeData(RED); //LED3  Red
delay(mSec);


printf("Blue.\n");
writeData(BLUE|nBrightness); //LED1 Blue
writeData(GREEN); //LED2 Green
writeData(RED); //LED3  Red
delay(mSec);


printf("Red+Green.\n");
writeData(BLUE); //LED1 Blue
writeData(GREEN|nBrightness); //LED2 Green
writeData(RED|nBrightness); //LED3 Red
delay(mSec);



printf("Red+Blue.\n");
writeData(BLUE|nBrightness); //LED1 Blue
writeData(GREEN); //LED2 Green
writeData(RED|nBrightness); //LED3  Red
delay(mSec);



printf("Blue+Green.\n");
writeData(BLUE|nBrightness); //LED1 Blue
writeData(GREEN|nBrightness); //LED2 Green
writeData(RED); //LED3  Red
delay(mSec);



printf("Red+Green+Blue.\n");
writeData(BLUE|nBrightness); //LED1 Blue
writeData(GREEN|nBrightness); //LED2 Green
writeData(RED|nBrightness); //LED3  Red
delay(mSec);


printf("press enter to change brightness.\n");
getchar();
}
}
}

return 0;
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值